在我的项目中,我使用EntityFramework 4来处理数据。我发现一个简单的查询可怕的性能问题。当我查看由EF4生成的SQL查询中的分析器时,我感到很震惊。实体框架中的Linq查询4.糟糕的性能
我有我的实体数据模型的一些表:
看起来很简单。我试图从所有相关导航属性中选择指定类别中的所有产品项目。
我写这个LINQ查询:
ObjectSet<ProductItem> objectSet = ...;
int categoryId = ...;
var res = from pi in objectSet.Include("Product").Include("Inventory").Include("Inventory.Storage")
where pi.Product.CategoryId == categoryId
select pi;
EF生成此SQL查询:
SELECT [Project1].[pintId1] AS [pintId],
[Project1].[pintId] AS [pintId1],
[Project1].[intProductId] AS [intProductId],
[Project1].[nvcSupplier] AS [nvcSupplier],
[Project1].[ nvcArticle] AS [ nvcArticle],
[Project1].[nvcBarcode] AS [nvcBarcode],
[Project1].[bIsActive] AS [bIsActive],
[Project1].[dtDeleted] AS [dtDeleted],
[Project1].[pintId2] AS [pintId2],
[Project1].[nvcName] AS [nvcName],
[Project1].[intCategoryId] AS [intCategoryId],
[Project1].[ncProductType] AS [ncProductType],
[Project1].[C1] AS [C1],
[Project1].[pintId3] AS [pintId3],
[Project1].[intProductItemId] AS [intProductItemId],
[Project1].[intStorageId] AS [intStorageId],
[Project1].[dAmount] AS [dAmount],
[Project1].[mPrice] AS [mPrice],
[Project1].[dtModified] AS [dtModified],
[Project1].[pintId4] AS [pintId4],
[Project1].[nvcName1] AS [nvcName1],
[Project1].[bIsDefault] AS [bIsDefault]
FROM (SELECT [Extent1].[pintId] AS [pintId],
[Extent1].[intProductId] AS [intProductId],
[Extent1].[nvcSupplier] AS [nvcSupplier],
[Extent1].[ nvcArticle] AS [ nvcArticle],
[Extent1].[nvcBarcode] AS [nvcBarcode],
[Extent1].[bIsActive] AS [bIsActive],
[Extent1].[dtDeleted] AS [dtDeleted],
[Extent2].[pintId] AS [pintId1],
[Extent3].[pintId] AS [pintId2],
[Extent3].[nvcName] AS [nvcName],
[Extent3].[intCategoryId] AS [intCategoryId],
[Extent3].[ncProductType] AS [ncProductType],
[Join3].[pintId1] AS [pintId3],
[Join3].[intProductItemId] AS [intProductItemId],
[Join3].[intStorageId] AS [intStorageId],
[Join3].[dAmount] AS [dAmount],
[Join3].[mPrice] AS [mPrice],
[Join3].[dtModified] AS [dtModified],
[Join3].[pintId2] AS [pintId4],
[Join3].[nvcName] AS [nvcName1],
[Join3].[bIsDefault] AS [bIsDefault],
CASE
WHEN ([Join3].[pintId1] IS NULL) THEN CAST(NULL AS int)
ELSE 1
END AS [C1]
FROM [ProductItem] AS [Extent1]
INNER JOIN [Product] AS [Extent2]
ON [Extent1].[intProductId] = [Extent2].[pintId]
LEFT OUTER JOIN [Product] AS [Extent3]
ON [Extent1].[intProductId] = [Extent3].[pintId]
LEFT OUTER JOIN (SELECT [Extent4].[pintId] AS [pintId1],
[Extent4].[intProductItemId] AS [intProductItemId],
[Extent4].[intStorageId] AS [intStorageId],
[Extent4].[dAmount] AS [dAmount],
[Extent4].[mPrice] AS [mPrice],
[Extent4].[dtModified] AS [dtModified],
[Extent5].[pintId] AS [pintId2],
[Extent5].[nvcName] AS [nvcName],
[Extent5].[bIsDefault] AS [bIsDefault]
FROM [Inventory] AS [Extent4]
INNER JOIN [Storage] AS [Extent5]
ON [Extent4].[intStorageId] = [Extent5].[pintId]) AS [Join3]
ON [Extent1].[pintId] = [Join3].[intProductItemId]
WHERE [Extent2].[intCategoryId] = 8 /* @p__linq__0 */) AS [Project1]
ORDER BY [Project1].[pintId1] ASC,
[Project1].[pintId] ASC,
[Project1].[pintId2] ASC,
[Project1].[C1] ASC
7000条记录在数据库中,并〜1000条记录中指定类别的这个查询的执行时间ID 10秒左右。
FROM [ProductItem] AS [Extent1]
INNER JOIN [Product] AS [Extent2]
ON [Extent1].[intProductId] = [Extent2].[pintId]
LEFT OUTER JOIN [Product] AS [Extent3]
ON [Extent1].[intProductId] = [Extent3].[pintId]
***LEFT OUTER JOIN (SELECT ....***
嵌套选择加入...太可怕了......我试图改变LINQ查询,但我得到相同的SQL查询输出:如果看看这个,这并不奇怪。
使用存储过程的解决方案对我来说是不可接受的,因为我正在使用SQL Compact数据库。
您的英语不是那么糟:)也是格式良好的问题。 +1 – Aren 2010-09-21 19:41:20
您可以使用http://imgur.com/分享图像。 – Steven 2010-09-21 19:41:45
包含什么?为什么不只是从pi的objectSet中pi.Product.CategoryId == categoryId select pi_? – 2010-09-21 19:42:03