2010-11-19 43 views
2

我們開始使用存儲過程將具有實體框架4的項目從VS2008遷移到VS2010作爲ORM。與LINQ to SQL生成的SQL相比,LINQ to Entities生成的SQL效率低下嗎?

現在我不得不做一個相當複雜的LINQ查詢來從我們的數據庫中獲取數據。我通常首先嚐試找出使用LINQPad的LINQ查詢(偉大的工具btw!)。

現在我已經注意到,與LINQ to SQL相比,LINQ to Entities生成的SQL是可怕的,它生成的SQL語句與我們以前用存儲過程類似。 L2E查詢有很多嵌套的SELECT和INNER JOINS,只是看着它而傷了我的頭!

這讓我很好奇,我選擇了另一個相當複雜的LINQ查詢,並將LINQ to Entites生成的SQL與LINQ to SQL生成的SQL進行了比較。結果是類似的,L2E SQL非常糟糕,而且可能非常低效(我沒有對它進行基準測試,但對於我來說,通過查看SQL語句很明顯)

對不起,我不能給一些示例查詢目前,但如果興趣足夠高,我可以建立一個虛擬數據庫,並創建類似於我們使用的查詢(混淆我們的查詢和表將使查詢無法讀取和毫無意義)

那麼什麼您是否使用實體框架?沒有人注意到糟糕的SQL語句,或者大多數人不關心嗎?我是否錯過了我應該知道的有關L2E的基本知識?

現在我非常遺憾,我們確實選擇了使用LINQ to SQL的實體框架。

編輯:

所以我做了一些基準和WOW,我很驚訝!我將生成的SQL語句放入SQL Server Management Studio中的查詢窗口中,並多次執行每個查詢。以下是在WHILE循環中執行查詢的平均結果1,10和100次。

1 time: 
    LINQ to SQL: 440ms 
    LINQ to Entities: 240ms 

10 times: 
    LINQ to SQL: 2900ms 
    LINQ to Entities: 910ms 

100 times: 
    LINQ to SQL: 31600ms 
    LINQ to Entities: 7000ms 

我真的很驚訝!

我的下一個測試是創建一個簡單的C#程序來生成和執行SQL語句。爲了方便,我使用了LINQpad。對於每次測試,我都使用LINQPad中的LINQ to SQL和LINQ to Entities數據提供程序。查詢每次完全一樣。 測試程序是這樣的:

void Main() 
{ 
    var sw = new Stopwatch(); 

    for(int i = 0; i < 5; i++) 
    { 
     sw.Start(); 
     for(int y = 0; y < 10; y++) 
     { 
      ExecuteQuery(); 
     } 
     sw.Stop(); 
     Console.WriteLine(string.Format("Pass {0}: {1}", i, sw.ElapsedMilliseconds)); 
     sw.Reset(); 
    } 
} 
private void ExecuteQuery() 
{ 
    //here is my 'complex' linq query 
    var dummy = (from p in....).ToList(); 
} 

這一次,我有點失望,結果如下:

 
LINQ to SQL: 
Run 0: 805 
Run 1: 726 
Run 2: 722 
Run 3: 717 
Run 4: 767 

LINQ to Entities: 
Run 0: 3031 
Run 1: 3231 
Run 2: 3085 
Run 3: 3127 
Run 4: 3148 

我想不同的是由於SQL語句生成?還是我基準測試完全錯了?建議?我已經在我們的項目中實現了LINQ查詢(忘記提及該項目是一個ASP.NET MVC 3 RC Web應用程序)。我們基本上是用自定義的網格顯示一個頁面。使用LINQ to Entities加載網格數據大約需要300-400ms!使用LINQ to SQL加載數據需要大約70-80ms。這實際上與我在上面的LINQPad中的測試應用中的結果非常相似。

我一直在尋找EF過去幾個小時的性能問題,並且發現了很多初始查詢的問題。事實上,最初的查詢速度較慢,但​​只有大約200毫秒,所以第一個查詢需要大約600毫秒,而其他後續查詢需要300-400毫秒。我也讀了precompiling views with EdmGen,但沒有什麼區別。我發現另一個blog post that compared LINQ to SQL performance with EF,結果似乎是相似的,雖然這是EF 3.5。然後我發現blog post about EF with heavy inheritance,但這不適用於我的情況。

除了上百個「初始查詢很慢」類型的帖子,我沒有發現任何與我的問題有關的東西。我的意思是,與Linq to SQL相比,我並不介意性能受到影響,但70ms與300ms的差別是巨大的!它確實會影響我們網絡應用程序的用戶體驗。

我要嘗試的最後一件事是預編譯查詢。如果性能沒有得到改善,那麼我可以切換到LINQ to SQL(儘管生成的SQL本身的速度確實更快!)

+0

我懷疑你的解決方案越抽象,生成SQL越難理解,因爲需要覆蓋更多的東西。即使這樣你可能會發現SQL解析器很好地優化了它。 – Lazarus 2010-11-19 16:05:21

+0

問題是,我使用完全相同的LINQ查詢並將其與LINQPad中的LINQ to Entites和LINQ to SQL提供程序進行對比,然後比較生成的SQL。或者,也許我不明白你的意見:) – Simon 2010-11-19 16:18:07

+0

你的第一個例子(while循環)的結果是錯誤標記的?從這個例子中可以看出,LINQ to Entities速度更快,似乎並不支持該帖子的其他內容。 – 2010-11-19 22:27:25

回答

2

當你說你實際上並不打算對性能進行基準測試。

僅僅因爲SQL看起來不好,這並不意味着它執行非常糟糕(所有的時間)。

當使用實體框架或LINQ to SQL時,我真的不在乎生成的語句是什麼樣子,只要我的應用程序仍然符合我的標準。只有性能下降超過可接受的水平時,我纔會麻煩微調查詢以獲得更好的SQL。

+0

有效點,我會做一些基準測試並回報。我的假設是,它會變慢,因爲L2E查詢長3倍,嵌套SELECT語句多3倍,所以也許SQL服務器本身在這裏做一些優化?誰知道,我會去做基準測試。 – Simon 2010-11-19 16:15:53