日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET状缓存Cache的应用-提高数据库读取速度

發布時間:2023/12/18 asp.net 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET状缓存Cache的应用-提高数据库读取速度 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
ASP.NET狀緩存Cache的應用-提高數據庫讀取速度 原文:ASP.NET狀緩存Cache的應用-提高數據庫讀取速度

一、 Cache概述
??
????既然緩存中的數據其實是來自數據庫的,那么緩存中的數據如何和數據庫進行同步呢?一般來說,緩存中應該存放改動不大或者對數據的實時性沒有太多要求的數據。這樣,我們只需要定期更新緩存就可以了。相反,如果緩存的更新頻率過快的話,使用緩存的意義就不是很大了,因此更新緩存的時候需要一次性從數據庫中讀取大量的數據,過于頻繁地更新緩存反而加重了數據庫的負擔。
那么ASP.NET中的Cache又提供了哪些緩存的過期策略呢?
· 永不過期。和Application一樣,緩存永不過期。
· 絕對時間過期。緩存在某一時間過期,比如5分鐘后。
· 變化時間過期(平滑過期)。緩存在某一時間內未訪問則超時過期,這個和Session有點類似,比如我們可以設定緩存5分鐘沒有人訪問則過期。
· 依賴過期。緩存依賴于數據庫中的數據或者文件中的內容。一旦數據庫中某些表的數據發生變動或者文件內容發生變動,則緩存自動過期。
緩存過期后我們就要更新緩存了,ASP.NET提供了兩種更新策略。
· 被動更新。緩存過期以后手動進行更新。
· 主動更新。緩存過期以后在回調方法中更新。


二、 Cache性能與過期策略


首先,在頁面上添加兩個按鈕,并雙擊按鈕實現Click事件處理方法。


程序代碼 <asp:Button ID="btn_GetDataFromCache" runat="server" OnClick="btn_GetData_Click"
Text="從緩存中讀取數據" />
<asp:Button ID="btn_GetDataFromDb" runat="server" OnClick="btn_GetDataFromDb_Click"
Text="從數據庫中讀取數據" />

第一個按鈕實現從緩存讀取數據。

注意:本例需要using以下命名空間。

程序代碼 using System.Diagnostics; // 用于精確測定時間間隔
using System.Web.Caching; // 用于緩存的策略
using System.IO;?? // 用于文件操作

protected void btn_GetData_Click(object sender, EventArgs e)
{
????InsertRecord();
????Stopwatch sw=new Stopwatch();
????sw.Start();
????if (Cache["Data"]==null)
????{
????????Response.Write("緩存無效<br/>");
????}
????else
????{
????????DataSet ds = Cache["Data"] as DataSet;
????????Response.Write(string.Format("查詢結果:{0}<br/>", ds.Tables[0].Rows[0][0]));
????????Response.Write(string.Format("耗費時間:{0}<br/>", sw.ElapsedTicks));
????}
}在這里有幾點需要說明。
· 一開始的InsertRecord()方法是我們自己創建的,用來向數據庫插入一條記錄。這樣,我們就能看出來數據是否是從緩存中讀取的了。
InsertRecord()方法如下:

程序代碼 private void InsertRecord()
{
????using (SqlConnection conn = new SqlConnection(@"server=(local)\SQLEXPRESS;
????database=Forum;Trusted_Connection=True"))
????{
????????conn.Open();
????????using (SqlCommand cmd = new SqlCommand("Insert into CacheTest (Test) values
?????? ('Test')", conn))
????????{
????????????cmd.ExecuteNonQuery();
????????}
????}
}
· 如果緩存存在則輸出查詢結果和查詢耗費的時間,如果緩存不存在則輸出“緩存無效”。
· Stopwatch類用于精確測定逝去的時間,ElapsedTicks屬性返回了間隔的計數器刻度,所謂計數器刻度就是系統的計數器走過了多少次。當然,Stopwatch還有ElapsedMilliseconds能返回間隔的總毫秒數。之所以使用ElapsedTicks,因為它是一個更小的時間單位。
第二個按鈕直接從數據庫讀取數據。

程序代碼 protected void btn_GetDataFromDb_Click(object sender, EventArgs e)
{
????InsertRecord();
????Stopwatch sw = new Stopwatch();
????sw.Start();
????DataSet ds = GetData();
????Response.Write(string.Format("查詢結果:{0}<br/>", ds.Tables[0].Rows[0][0]));
????Response.Write(string.Format("耗費時間:{0}<br/>", sw.ElapsedTicks));
}在這里,我們把讀取數據的操作使用一個GetData()方法進行了封裝,方法實現如下:

程序代碼 private DataSet GetData()
{
????DataSet ds = new DataSet();
????using (SqlConnection conn = new SqlConnection(@"server=(local)\SQLEXPRESS;
????database=Forum;Trusted_Connection=True"))
????{
????????SqlDataAdapter da = new SqlDataAdapter("select count(*) from CacheTest", conn);
????????da.Fill(ds);????????????
????}
????return ds;
}
為了能體現出緩存的效率,我們在Forum數據庫中又新建立了一個CacheTest數據表,表結構很簡單,如圖4-1所示。

圖4-1??CacheTest表結構
我們在表中插入了10萬條以上的記錄,使得表的大小達到了100MB左右。
運行程序,單擊“從數據庫中讀取數據”按鈕,如圖4-2所示,

圖4-2 從數據庫讀取數據需要花費大量的時間

我們可以看到,這個操作耗費了相當多的時間。
因為我們直接從數據庫讀取count(*),所以每次單擊按鈕查詢結果顯示的數字都會+1。現在你單擊“從緩存中讀取數據”肯定是顯示“緩存無效”,因為我們還沒有添加任何緩存。
然后,我們在頁面上添加三個按鈕并雙擊按鈕創建事件處理方法,三個按鈕使用不同的過期策略添加緩存。

程序代碼 <asp:Button ID="btn_InsertNoExpirationCache" runat="server" Text="插入永不過期緩存"
OnClick="btn_InsertNoExpirationCache_Click" />
<asp:Button ID="btn_InsertAbsoluteExpirationCache" runat="server" Text="插入絕對時間
過期緩存" OnClick="btn_InsertAbsoluteExpirationCache_Click" />
<asp:Button ID="btn_InsertSlidingExpirationCache" runat="server" Text="插入變化時間
過期緩存" OnClick="btn_InsertSlidingExpirationCache_Click" />
三個按鈕的Click事件處理方法如下:

程序代碼 protected void btn_InsertNoExpirationCache_Click(object sender, EventArgs e)
{
????DataSet ds = GetData();
????Cache.Insert("Data", ds);
}
protected void btn_InsertAbsoluteExpirationCache_Click(object sender, EventArgs e)
{
????DataSet ds = GetData();
????Cache.Insert("Data", ds,null, DateTime.Now.AddSeconds(10), TimeSpan.Zero);
}
protected void btn_InsertSlidingExpirationCache_Click(object sender, EventArgs e)
{
????DataSet ds = GetData();
????Cache.Insert("Data", ds, null, DateTime.MaxValue, TimeSpan.FromSeconds(10));
}我們來分析一下這三種過期策略。
· 永不過期。直接賦值緩存的Key和Value即可
· 絕對時間過期。DateTime.Now.AddSeconds(10)表示緩存在10秒后過期,TimeSpan.Zero表示不使用平滑過期策略。
· 變化時間過期(平滑過期)。DateTime.MaxValue表示不使用絕對時間過期策略,TimeSpan.FromSeconds(10)表示緩存連續10秒沒有訪問就過期。
在這里,我們都使用了Insert()方法來添加緩存。其實,Cache還有一個Add()方法也能向緩存中添加項。不同之處在于Add()方法只能添加緩存中沒有的項,如果添加緩存中已有的項將失敗(但不會拋出異常),而Insert()方法能覆蓋原來的項。
注意:和Application不同,這里不需要使用在插入緩存的時候進行鎖操作,Cache會自己處理???? 并發。
現在,我們就可以打開頁面對這三種過期策略進行測試了。
1.單擊“從緩存中讀取數據”按鈕,提示“緩存無效”。
2.單擊“從數據庫中讀取數據”按鈕,查詢結果顯示現在記錄總數為100646。
3.單擊“插入永不過期緩存”按鈕,然后連續單擊“從緩存中讀取數據”按鈕,可以發現,無論過去多久,緩存始終沒有過期,而且觀察記錄查詢結果可以發現值始終沒有發生變化。不同的是,從緩存中讀取數據的效率比從數據庫中讀取數據提高了幾個數量級,如圖4-3所示,你可以和圖4-2進行比較。

圖4-3??從緩存中讀取數據所花費的時間
4.單擊“插入絕對時間過期緩存”,然后連續單擊“從緩存中讀取數據”按鈕,大約10秒過期后,頁面提示“緩存無效”,說明緩存過期了。
5.單擊“插入變化時間過期緩存”,然后連續單擊“從緩存中讀取數據”按鈕,緩存始終不過期,如果我們等待10秒后再去單擊按鈕,頁面提示“緩存無效”,說明緩存過期了。
我們再來看一下依賴過期策略。所謂依賴過期就是緩存的依賴項(比如一個文件)的內容改變之后緩存也就失效了。由于篇幅關系,這里只介紹文件依賴。我們在頁面上再加兩個按鈕并雙擊按鈕添加Click事件處理方法。

程序代碼 <asp:Button ID="btn_ModifyFile" runat="server" Text="修改文件" OnClick="btn_ModifyFile_
Click" />
<asp:Button ID="btn_AddFileDependencyCache" runat="server" Text="插入文件依賴緩存"
OnClick="btn_AddFileDependencyCache_Click" />

在本例中,我們將使緩存依賴一個txt文本文件。因此,首先在項目中添加一個test.txt文本文件。單擊“修改文件”按鈕實現文件的修改。

程序代碼 protected void btn_ModifyFile_Click(object sender, EventArgs e)
{
????FileStream fs = new FileStream(Server.MapPath("test.txt"), FileMode.Append,
????FileAccess.Write);
????StreamWriter sw = new StreamWriter(fs);
????sw.WriteLine(DateTime.Now.ToString());
????sw.Close();
????fs.Close();
}

我們通過在文件的最后寫入當前的時間來修改文件。插入文件依賴緩存按鈕的事件處理方法如下:

程序代碼 protected void btn_AddFileDependencyCache_Click(object sender, EventArgs e)
{
????CacheDependency cd = new CacheDependency(Server.MapPath("test.txt"));
????DataSet ds = GetData();
????Cache.Insert("Data", ds, cd);
}添加文件依賴緩存同樣簡單,通過CacheDependency關聯了一個文件依賴。
現在就可以打開頁面進行測試了。
1.單擊“從緩存中讀取數據”按鈕,提示“緩存無效”。
2.單擊“從數據庫中讀取數據”按鈕,查詢結果顯示現在記錄總數為100710。
3.單擊“插入文件依賴緩存”按鈕,然后連續單擊“從緩存中讀取數據”按鈕,可以發現,無論過去多久,緩存始終沒有過期,而且觀察記錄查詢結果可以發現值始終沒有發生變化。
4.單擊“修改文件”按鈕,然后單擊“從緩存中讀取數據”按鈕,提示“緩存無效”。由于文件已經修改了,依賴這個文件的緩存立刻失效了。


三、??Cache的更新策略
最后,我們來討論緩存的更新策略。在Web程序中我們通常會使用被動更新。所謂被動更新,就是在調用數據的時候判斷緩存是否為空,如果為空則先更新緩存然后再從緩存中讀取數據,如果不為空則直接從緩存中讀取數據。可以把“從緩存中讀取數據”按鈕的Click事件處理方法修改成如下,實現被動更新。


程序代碼 protected void btn_GetData_Click(object sender, EventArgs e)
{
????InsertRecord();
????DataSet ds = new DataSet();
????Stopwatch sw = new Stopwatch();
????sw.Start();
????if (Cache["Data"] == null)
????{
????????ds = GetData();
????????Cache.Insert("Data", ds, null, DateTime.Now.AddSeconds(10), TimeSpan.Zero);
????}
????else
????{
????????ds = Cache["Data"] as DataSet;
????}
????Response.Write(string.Format("查詢結果:{0}<br/>", ds.Tables[0].Rows[0][0]));??
????Response.Write(string.Format("耗費時間:{0}<br/>", sw.ElapsedTicks));
}
我們可以看出,如果沒有人訪問數據緩存是不會更新的,只有緩存被訪問的時候發現緩存無效才會去更新。這樣很明顯的一個缺點就是,如果緩存過期了更新操作將花費很長時間,這個時候的查詢也需要花費很多時間。我們可以利用緩存的回調功能讓緩存過期后自動續建實現自動更新的目的。

程序代碼 protected void btn_InsertActiveUpdateCache_Click(object sender, EventArgs e)
{
????DataSet ds = GetData();
????Cache.Insert("Data", ds, null, DateTime.Now.AddSeconds(10), TimeSpan.Zero,
????CacheItemPriority.Default, CacheRemovedCallback);
}
最后一個參數表明緩存被移除以后自動調用CacheRemovedCallback()方法,方法實現如下。

程序代碼 private void CacheRemovedCallback(String key, object value, CacheItemRemovedReason
removedReason)
{
????DataSet ds = GetData();
????Cache.Insert(key, ds, null, DateTime.Now.AddSeconds(10), TimeSpan.Zero, CacheItemPriority.
????Default, CacheRemovedCallback);
}

在回調方法中,我們再次插入一個支持回調的緩存。這樣,緩存被移除以后又能自動更新了。說了這么多創建緩存的方法,讀者可能會問怎么手動移除緩存呢?比如我們要移除Key="Data"的緩存只需要:
Cache.Remove("Data");

你可能會馬上想到用Cache.RemoveAll()方法移除所有緩存,可是Cache沒有提供這樣的方法,我們只能通過遍歷來實現移除所有緩存。

程序代碼 IDictionaryEnumerator CacheEnum = HttpRuntime.Cache.GetEnumerator();
while (CacheEnum.MoveNext())
{
????Cache.Remove(CacheEnum.Key.ToString());
}


四、??Cache總結
同樣,我們以第一節中的幾個問題結束對Cache的討論。
· 存儲的物理位置。服務器內存。
· 存儲的類型限制。任意類型。
· 狀態使用的范圍。當前請求上下文,所有用戶共用一份。
· 存儲的大小限制。任意大小。
· 生命周期。有多種過期策略控制緩存的銷毀。
· 安全與性能。數據總是存儲在服務端,安全性比較高,但不易存儲過多數據。
· 優缺點與注意事項。檢索數據速度快,過期策略豐富。注意別把對實時性要求很高的數據放到Cache中,不斷更新Cache會對數據庫造成壓力。

posted on 2015-12-09 08:59 NET未來之路 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/lonelyxmas/p/5031741.html

總結

以上是生活随笔為你收集整理的ASP.NET状缓存Cache的应用-提高数据库读取速度的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。