![](/img/trans.png)
[英]Why does Entity Framework 6 generate complex SQL queries for simple lookups?
[英]Why does Entity Framework generate slow overengineered SQL?
我有這個代碼:
DbSet<TableName> table = ...// stored reference
var items = from n in table where
n.Name.ToUpper().Contains(searchString.ToUpper().Trim())
select n;
WriteToLog( items.ToString() );
最后一行輸出生成的SQL。 這是我得到的:
SELECT
[Extent1].[Name] AS [Name],
// all the other columns follow
FROM (SELECT
[TableName].[Name] AS [Name],
// all the other columns follow
FROM [dbo].[TableName] AS [TableName]) AS [Extent1]
WHERE ( CAST(CHARINDEX(LTRIM(RTRIM(UPPER(@p__linq__0))), UPPER([Extent1].[Name])) AS int)) > 0
你看,有SELECT
FROM- SELECT
雖然它是完全冗余的 - 一個SELECT
就足夠了。 使用EF的代碼運行時間超過半分鍾,並且該查詢超時,盡管表格相當小。
為什么會生成這種過度設計的SQL查詢,如何使EF生成更好的查詢?
它通過轉換表達式樹來生成結果SQL。 它似乎過度設計(例如,使用子查詢)作為轉換完成方式的副作用。 轉換的細節是專有的和復雜的,結果不應該是人類可讀的。
問題並不完全清楚 - 你正試圖解決一個我認為可能不是問題的問題。 嘗試比較生成的查詢和您自己的查詢 - 我猜想查詢優化器將做出如此簡單的優化的簡短工作。
我的猜測(這可能是你可以得到的最好的答案,除非LINQ to Entities MS dev出現)是他們正在做的那樣:產生最有效的查詢,但留下令人頭疼的困難工作將查詢優化到他們已經將數百或數千個工作日放入的位:SQL Server中的查詢優化器。
它執行額外的Select
但選擇沒有相關的成本。 您可以看到估計的查詢計划,它將顯示0%
成本。 這樣做是因為EF與Oracle,SQL服務器等各種RDBMS系統兼容,並確保它可能實現最大兼容性。
但是我確實同意Entity Framework生成UGLY sql。 您提供的示例是一個非常簡單的Linq查詢,當您的查詢開始變得復雜時,您會看到更多的丑陋。
1)雖然這可能會或可能不會回答您的答案,但我會說使用像PetaPoco這樣的微型ORM:
https://github.com/toptensoftware/PetaPoco
或Dapper.Net
https://github.com/SamSaffron/dapper-dot-net
我一直在我的一個項目中使用它,我完全滿意你用簡單的Ado.Net獲得的原始速度。
2)我的第二個建議是始終使用至少 Select
語句的存儲過程。 對於插入,更新和刪除,您應該使用EF並利用更改跟蹤機制,這樣可以節省您編寫繁瑣查詢的時間,但至少應該嘗試使用純SQL的Select語句,這使您可以更自由地使用SQL產生。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.