linq to sql 系列之 linq to sql效能最佳化技巧

來源:互聯網
上載者:User

linq to sql 是一個代碼產生器和ORM工具,他自動為我們做了很多事情,這很容易讓我們對他的效能產生懷疑。但是也有幾個測試證明顯示在做好最佳化的情況下,linq to sql的效能可以提升到ado.net datareader效能的93%。

因此我總結了linq to sql的10個效能提升點,來最佳化其查詢和修改的效能。

1. 不需要時要關閉 DataContext的ObjectTrackingEnabled 屬性

using (NorthwindDataContext context = new NorthwindDataContext()){  context.ObjectTrackingEnabled = false;}

關閉這個屬性會使linq to sql停止對對象的標識管理和變化跟蹤。但值得注意的是關閉ObjectTrackingEnabled 意味著也將DeferredLoadingEnabled屬性設定為false,當訪問相關表時會返回null。

2. 不要把所有的資料對象都拖到一個DataContext中

一個DataContext代表一個工作單元,並非整個資料庫。如果幾個資料庫物件之間沒有關係,或者在程式中用不到的資料庫物件(例如日誌表,大量操作表等等),讓這些對象消耗記憶體空間和DataContext對象Tracing Service是完全沒有必要的。

建議將所有的資料庫物件按工作單元分給幾個DataContext來處理。你也可以通過建構函式配置這些DataContext使用相同的資料庫連接,這樣也可以發揮據庫串連池的用途。

3. CompiledQuery --- 有必要就得用

在建立一個linq to sql運算式並將它轉換成對應的sql語句執行的過程,需要幾個關鍵的步驟

 1) 建立運算式樹狀架構
 2) 轉換成sql
 3) 運行sql語句
 4) 取回資料
 5) 將資料轉換成對象

很顯然,當我們一遍又一遍的執行相同的查詢時,上面1),2)兩個步驟重複執行是在浪費時間。使用System.Data.Linq命名空間下的CompiledQuery類的Compile方法可以避免這種浪費。

請看下面的使用樣本:

Func<NorthwindDataContext, IEnumerable<Category>> func =   CompiledQuery.Compile<NorthwindDataContext, IEnumerable<Category>>   ((NorthwindDataContext context) => context.Categories.      Where<Category>(cat => cat.Products.Count > 5));

func變數現在是一個已經編譯後的查詢,他只需要在第一次運行時編譯一次,就可以重複使用,現在我們將其儲存到一個靜態類中,如下所示:

/// <summary>/// Utility class to store compiled queries/// </summary>public static class QueriesUtility{  /// <summary>  /// Gets the query that returns categories with more than five products.  /// </summary>  /// <value>The query containing categories with more than five products.</value>  public static Func<NorthwindDataContext, IEnumerable<Category>>    GetCategoriesWithMoreThanFiveProducts    {      get      {        Func<NorthwindDataContext, IEnumerable<Category>> func =          CompiledQuery.Compile<NorthwindDataContext, IEnumerable<Category>>          ((NorthwindDataContext context) => context.Categories.            Where<Category>(cat => cat.Products.Count > 5));        return func;      }    }}

如何使用它呢,請看下面的程式碼片段:

using (NorthwindDataContext context = new NorthwindDataContext()){  QueriesUtility.GetCategoriesWithMoreThanFiveProducts(context);}

4. 使用DataLoadOptions.AssociateWith設定僅從資料庫中取需要的資料

請參考:http://www.cnblogs.com/yukaizhao/archive/2010/05/17/linq_to_sql_DeferredLoadingEnabled_dataloadoption_loadwith_associatewith.html
5. 僅在需要時開啟積極並發控制,換句話說如果不需要請將列的UpdateCheck屬性設定為UpdateCheck.Never,這樣在更新和刪除時可以減少不必要的條件判斷

[Column(Storage=“_Description”, DbType=“NText”,            UpdateCheck=UpdateCheck.Never)]public string Description{  get  {    return this._Description;  }  set  {    if ((this._Description != value))    {      this.OnDescriptionChanging(value);      this.SendPropertyChanging();      this._Description = value;      this.SendPropertyChanged(“Description”);      this.OnDescriptionChanged();    }  }}

可以參考:http://www.cnblogs.com/yukaizhao/archive/2010/05/13/linq_to_sql_1.html 這篇文章中的第三點。

6. 經常設定DataContext.Log查看linq to sql執行時使用的sql,分析取回的資料是否剛好夠用。

using (NorthwindDataContext context = new NorthwindDataContext()){  context.Log = Console.Out;}

7. 僅在有必要時使用Attach方法。

在linq to sql中對象附加是一個的非常好用的機制,但是什麼事情都不是免費的。當在DataContext中Attach對象時,就意味著過一段時間你會使用這個對象,DataContext會給這個對象做“馬上要做修改的”標記。

但是有時候Attach並非必要,例如使用AttachAll去附加一個集合,這個集合中的元素並非都會發生變化。

8. 注意實體標識管理的開銷

在一個非唯讀DataContext中,對象一直會被跟蹤,因此要知道在非直覺的情況下也可能會導致DataContext做對象跟蹤,請看下面的代碼

using (NorthwindDataContext context = new NorthwindDataContext()){  var a = from c in context.Categories  select c;}

非常簡單,就是一個最基本的linq查詢,讓我們再看下另一個語句

using (NorthwindDataContext context = new NorthwindDataContext()){  var a = from c in context.Categories  select new Category  {    CategoryID = c.CategoryID,    CategoryName = c.CategoryName,    Description = c.Description  };}

這兩種寫法哪一種更快呢,事實證明第二個語句比第一個要快得多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來了,使用它也是需要付出代價的。

最後希望這些技巧對你有用。歡迎發表評論。

本文是翻譯文章;

原文請看 http://www.sidarok.com/web/blog/content/2008/05/02/10-tips-to-improve-your-linq-to-sql-application-performance.html

 

linq to sql相關隨筆:

1.  從CUD開始,如何使用LINQ  to SQL插入、修改、刪除資料

2.  查詢 使用LINQ to SQL做簡單查詢

3.  查詢 消極式載入與立即載入,使用LoadWith和AssociateWith

4.  查詢 inner join,left outer join

5.  Linq to SQL中的彙總grouping having

6.  LINQ to SQL查詢最佳化,需要憂慮效能嗎?

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.