我們開始使用存儲過程將具有實體框架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本身的速度確實更快!)
我懷疑你的解決方案越抽象,生成SQL越難理解,因爲需要覆蓋更多的東西。即使這樣你可能會發現SQL解析器很好地優化了它。 – Lazarus 2010-11-19 16:05:21
問題是,我使用完全相同的LINQ查詢並將其與LINQPad中的LINQ to Entites和LINQ to SQL提供程序進行對比,然後比較生成的SQL。或者,也許我不明白你的意見:) – Simon 2010-11-19 16:18:07
你的第一個例子(while循環)的結果是錯誤標記的?從這個例子中可以看出,LINQ to Entities速度更快,似乎並不支持該帖子的其他內容。 – 2010-11-19 22:27:25