2017-01-16 54 views
3

我想知道爲什麼Entity框架會生成如此低效的SQL查詢。在我的代碼我預計其中一旦該行動INCLUDE:實體框架生成效率低下的SQL

db.Employment.Where(x => x.Active).Include(x => x.Employee).Where(x => x.Employee.UserID == UserID) 

但我結束了一個雙重SQL JOIN:

SELECT [x].[ID], [x].[Active], [x].[CurrencyID], [x].[DepartmentID], [x].[EmplEnd], [x].[EmplStart], [x].[EmployeeID], [x].[HolidayGroupID], [x].[HourlyCost], [x].[JobTitle], [x].[ManagerID], [x].[WorkScheduleGroupID], [e].[ID], [e].[Active], [e].[Address], [e].[BirthDate], [e].[CitizenshipID], [e].[City], [e].[CountryID], [e].[Email], [e].[FirstName], [e].[Gender], [e].[LastName], [e].[Note], [e].[Phone], [e].[PostalCode], [e].[TaxNumber], [e].[UserID] 
FROM [Employment] AS [x] 
INNER JOIN [Employee] AS [x.Employee] ON [x].[EmployeeID] = [x.Employee].[ID] 
INNER JOIN [Employee] AS [e] ON [x].[EmployeeID] = [e].[ID] 
WHERE ([x].[Active] = 1) AND ([x.Employee].[UserID] = @__UserID_0) 

我發現這個查詢將創造更好的SQL:

db.Employment.Where(x => x.Active).Where(x => x.Employee.UserID == UserID) 

SELECT [x].[ID], [x].[Active], [x].[CurrencyID], [x].[DepartmentID], [x].[EmplEnd], [x].[EmplStart], [x].[EmployeeID], [x].[HolidayGroupID], [x].[HourlyCost], [x].[JobTitle], [x].[ManagerID], [x].[WorkScheduleGroupID] 
FROM [Employment] AS [x] 
INNER JOIN [Employee] AS [x.Employee] ON [x].[EmployeeID] = [x.Employee].[ID] 
WHERE ([x].[Active] = 1) AND ([x.Employee].[UserID] = @__UserID_0) 

但是,這裏引用的實體不會從數據庫中檢索到的問題。

爲什麼兩個代碼不會生成相同的SQL?

+0

首先,您應該比較他們的查詢計劃 - 他們可能是相同的。 –

+0

我在這裏沒有看到這一點,我使用EF作爲SQL的一個抽象層,如果我必須一直到查詢計劃,我可能更適合自己編寫SQL,而不是讓EF來執行它。 – Marko

+0

在應用Include之後,您可以在使用&&運算符的方法中將兩個條件組合在一起。這應該會產生不同的查詢。 –

回答

3

由於語句不同,SQL有所不同。

實體框架確實會產生低效的TSQL,它總是有。通過抽象出具有良好性能的SQL所需的微妙之處,並用「腰帶和大括號」代替它們。總是可以替代你的sacrafice性能以達到效用。

如果您需要良好的性能,請自己編寫SQL。 Dapper適合我。您無法切實期待「一刀切」解決方案爲您的特定情況提供最佳代碼。您可以全面或全面地執行此操作。

除非您有大量或具體的性能需求,否則請使用它並使用任何您發現最簡單的東西。如果您需要將查詢調整到數據庫,您將瞭解數據庫引擎的詳細信息並自行實施查詢。如果您希望實體框架的下一次迭代成爲神奇的子彈,讓您以最少的知識獲得快速,高效的SQL數據訪問,祝您好運。

P.S.

題外,但NoSQL也許不是答案,只是一個不同類的數據庫。

+0

除此之外,SQL文本是不同的,但查詢計劃可能/可能在您的上下文中是相同的。 EF總是生成效率低下的SQL。您可以隨時監控最昂貴的查詢,並將EF從該區域切換到使用Dapper或類似的調用sprocs。 NoSql不是您的場景中的答案。 –

+0

不,查詢計劃是不一樣的,這就是問題所在。然而,我明白我不能相信EF爲甚至更復雜的查詢生成良好的SQL,如顯示的JOIN。 – Marko

+0

@Marko我明白你的失望。如果數據庫模型包含有關指標,數據統計信息和更多約束條件的信息,則理論上它可以提供更高效和安全的查詢。但是,我看到兩個缺點,即與SQL Server的這個版本緊密結合的很多工作,以及ORM試圖「保護」非數據庫開發人員的物理細節。 – Jodrell