本文將從一個執行個體講述.NET應用訪問資料庫的開銷問題。作者主要是從.NET應用訪問資料庫的遍曆順序改進講起。當然,與之配套的也就是我們熟悉的SQL Server資料庫。
拿今天的一個例子說話吧,那就表中存放的是全國的地區資訊,表結構如下:
首先用代碼產生器和預存程序產生器產生基本表的操作,推薦兩個工具:動軟.Net代碼產生器- 全功能的三層架構.Net代碼產生器和codeplex上面的一個預存程序產生工具Stored Procedure Generator (for SQL Server 2000/2005 ... 。
現在提供了一個方法,可以擷取頂級和二級地區的資訊,最開始的做法是先擷取頂級的地區資訊,然後迴圈頂級地區資訊,擷取它的子節點。
- List<KB.DSN.Entity.District> topDistrictList = new List<KB.DSN.Entity.District>();
- KB.DSN.BusinessAccess.District dictrictBll = new KB.DSN.BusinessAccess.District();
- topDistrictList = dictrictBll.GetEntityList(string.Format("DisFatherCode='{0}' {1}", 0, Settings.District_Order_By));
-
- foreach (KB.DSN.Entity.District dis in topDistrictList)
- {
- dis.ChildrenDis = dictrictBll.GetEntityList(string.Format("DisFatherCode='{0}' {1}", dis.DisCode, Settings.District_Order_By));
-
- }
- return topDistrictList;
上面的做法,可以實現功能,最後測試擷取一級和二級的地區資訊,花費時間5秒左右,不說能接受吧,起碼可以忍受。HttpWatch: An HTTP Viewer and HTTP Sniffer for IE and Firefox 這個工具可以查看瀏覽器擷取資料的時間。
後面又寫了一個方法,可以根據地區編號和想要擷取的層級數目,擷取指定地區下面的N層地區。和上面差不多,完成後一次是,一次擷取上海下面的二級花費10秒,擷取三級50秒。這好像就不能忍受了吧。
然後進行最佳化,代碼如下,變成一次擷取二級的資料,然後用C#代碼來產生層級關係。
- List<KB.DSN.Entity.District> districtList = new List<KB.DSN.Entity.District>();
- KB.DSN.BusinessAccess.District dictrictBll = new KB.DSN.BusinessAccess.District();
- districtList = dictrictBll.GetEntityList(string.Format(" {0} {1}", Settings.Get_Top_And_Second_District_Where,
- Settings.District_Order_By));
- var top = from c in districtList
- where c.DisFatherCode.Trim() == "0"
- select c;
- var second = from c in districtList
- where c.DisFatherCode.Trim() != "0"
- select c;
-
- foreach (KB.DSN.Entity.District dis in top)
- {
- var se = from c in second
- where c.DisFatherCode == dis.DisCode
- select c;
- dis.ChildrenDis = se as List<KB.DSN.Entity.District>;
- }
- return top as List<KB.DSN.Entity.District>;
作者後續
提到資料庫的訪問,尤其是遞迴層級調用問題,應該減少往返資料庫的次數,而是從資料庫將所需資料一次性擷取出來,然後在C#代碼中處理成樹形層級關係,這樣會提升很大的效率。
其實遞迴這種東西,用在數值計算中還可以,如果是複雜處理就最好不用了,很消耗CPU和記憶體的,因為要使用棧存放很多內容。只是代碼看起來好理解,量大、操作複雜還是轉成非遞迴的好。
如果層級不多,變化不大,可以考慮使用緩衝,效率就會更高。具體緩衝的應用可以參看李天平的:系統緩衝全解析 ,後面我可能也會寫一兩篇這方面的文章。
上一篇我們討論的資料是全國的行政地區資訊,它有固定的格式。每個行政區劃的編碼長度都是12位,總共分5級來管理,前兩位代表31個省直轄市),往後兩位代表一般的市州),往後兩位代表市中的區縣),往後三位是街道辦事處,最後三位是居民委員會社區)。
系統中其實有很多類似的類型編碼都被 放在資料庫中,有的是一級的,有的是分層級關係的。就像上面的地區資訊,全國的5級總共有8萬左右條資料。最好的辦法是一次將他們讀取到伺服器的記憶體中,形成樹形層級,放在緩衝中,如果有需要就直接擷取返回給用戶端,這樣可以較少很多的資料庫消耗。當然,前提是這類資訊的變動很小,幾乎沒有變化。系統緩衝全解析6:資料庫緩衝依賴 中介紹了,可以使用資料庫依賴緩衝,這樣就不怕資料庫內容有變化了,如果有變化,會自動更新緩衝。緩衝的正確使用,可以極大的提供效率
原文標題:NET應用訪問資料庫之資料庫的開銷問題
連結:http://www.cnblogs.com/virusswb/archive/2010/03/05/1679383.html