linq to sql 是一個代碼生成器和ORM工具,他自動爲我們做了很多事情,這很容易讓我們對他的性能產生懷疑。但是也有幾個測試證明顯示在做好優化的情況下,linq to sql的性能可以提升到ado.net datareader性能的93%。
轉自:http://www.cnblogs.com/yukaizhao/archive/2010/05/21/linq-to-sql-10-performance-tips.html
因此我總結了linq to sql的10個性能提升點,來優化其查詢和修改的性能。
1. 不需要時要關閉 DataContext的ObjectTrackingEnabled 屬性
關閉這個屬性會使linq to sql停止對對象的標識管理和變化跟蹤。但值得注意的是關閉ObjectTrackingEnabled 意味着也將DeferredLoadingEnabled屬性設置爲false,當訪問相關表時會返回null。
2. 不要把所有的數據對象都拖到一個DataContext中
一個DataContext代表一個工作單元,並非整個數據庫。如果幾個數據庫對象之間沒有關係,或者在程序中用不到的數據庫對象(例如日誌表,批量操作表等等),讓這些對象消耗內存空間和DataContext對象跟蹤服務是完全沒有必要的。
建議將所有的數據庫對象按工作單元分給幾個DataContext來處理。你也可以通過構造函數配置這些DataContext使用相同的數據庫連接,這樣也可以發揮據庫連接池的用途。
3. CompiledQuery --- 有必要就得用
在創建一個linq to sql表達式並將它轉換成對應的sql語句執行的過程,需要幾個關鍵的步驟
1) 創建表達式樹
2) 轉換成sql
3) 運行sql語句
4) 取回數據
5) 將數據轉換成對象
很顯然,當我們一遍又一遍的執行相同的查詢時,上面1),2)兩個步驟重複執行是在浪費時間。使用System.Data.Linq命名空間下的CompiledQuery類的Compile方法可以避免這種浪費。
請看下面的使用示例:
func變量現在是一個已經編譯後的查詢,他只需要在第一次運行時編譯一次,就可以重複使用,現在我們將其存儲到一個靜態類中,如下所示:
如何使用它呢,請看下面的代碼片段:
4. 使用DataLoadOptions.AssociateWith設置僅從數據庫中取需要的數據
請參考:http://www.cnblogs.com/yukaizhao/archive/2010/05/17/linq_to_sql_DeferredLoadingEnabled_dataloadoption_loadwith_associatewith.html
5. 僅在需要時打開積極併發控制,換句話說如果不需要請將列的UpdateCheck屬性設置爲UpdateCheck.Never,這樣在更新和刪除時可以減少不必要的條件判斷
可以參考:http://www.cnblogs.com/yukaizhao/archive/2010/05/13/linq_to_sql_1.html 這篇文章中的第三點。
6. 經常設置DataContext.Log查看linq to sql執行時使用的sql,分析取回的數據是否剛好夠用。
7. 僅在有必要時使用Attach方法。
在linq to sql中對象附加是一個的非常好用的機制,但是什麼事情都不是免費的。當在DataContext中Attach對象時,就意味着過一段時間你會使用這個對象,DataContext會給這個對象做“馬上要做修改的”標記。
但是有時候Attach並非必要,例如使用AttachAll去附加一個集合,這個集合中的元素並非都會發生變化。
8. 注意實體標識管理的開銷
在一個非只讀的DataContext中,對象一直會被跟蹤,因此要知道在非直覺的情況下也可能會導致DataContext做對象跟蹤,請看下面的代碼
1
2
3
4
5
|
using
(NorthwindDataContext context = new
NorthwindDataContext()) { var a =
from c
in context.Categories select c; } |
非常簡單,就是一個最基本的linq查詢,讓我們再看下另一個語句
這兩種寫法哪一種更快呢,事實證明第二個語句比第一個要快得多http://blogs.msdn.com/ricom/archive/2007/06/29/dlinq-linq-to-sql-performance-part-3.aspx
爲什麼呢? 因爲在第一個查詢中查詢出的每一個對象都需要存儲在DataContext中,並對他們做可能會發生變化的跟蹤,而在第二個查詢中你生命了一個新的對象,就不需要再做跟蹤了,所以第二個語句效率會高一些。
9. Linq to sql 提供了Take和Skip方法,使用他們來取需要的記錄,不要把整個表中的記錄都取下來
10. 不要濫用CompiledQuery 方法,如果你確認某個查詢只會執行一遍,那就不要使用CompiledQuery來了,使用它也是需要付出代價的。
最後希望這些技巧對你有用。歡迎發表評論。
本文是翻譯文章;
linq to sql相關隨筆:
1. 從CUD開始,如何使用LINQ to SQL插入、修改、刪除數據
3. 查詢 延遲加載與立即加載,使用LoadWith和AssociateWith
4. 查詢 inner join,left outer join