我遇到了一些性能问题。我得到了以下数据库模型。
我希望选择 Entity2 中所有在 Entity1 中没有外键的条目,换句话说,导航属性必须为空。
我提出了以下 LINQ 查询context.Entity2Set.Where(x => x.Entity1 == null);
,它可以工作,但是速度很慢。所以我想知道是否有更好(更快)的方式(除了索引)来选择条目。
最后我想从Entity4中选择条目,所以性能是一个问题。
我遇到了一些性能问题。我得到了以下数据库模型。
我希望选择 Entity2 中所有在 Entity1 中没有外键的条目,换句话说,导航属性必须为空。
我提出了以下 LINQ 查询context.Entity2Set.Where(x => x.Entity1 == null);
,它可以工作,但是速度很慢。所以我想知道是否有更好(更快)的方式(除了索引)来选择条目。
最后我想从Entity4中选择条目,所以性能是一个问题。
您正在查询关系 ( Entity2
) 中的主体,而不是依赖关系 ( Entity1
)。这意味着外键在 table 中Entity1
,并且生成的 SQL 查询不仅仅是对 table 中列值的查询Entity2
。为了获得所需的结果,SQL 查询必须连接(通过LEFT OUTER JOIN
)这两个表。
如果它是一对多关系,您的查询就像:“获取所有没有订单项目的订单。” 这不能通过Order
单独检查表来实现,因为外键在表中OrderItem
,并且查询必须连接两个表。实际上,在此示例中,可以通过索引 table 中的外键列来提高查询的性能OrderItem
。
不幸的是,在您的示例中,您无法通过索引列来改进查询,因为您具有一对一的关系(而不是一对多)。由于 EF 的一对一关系始终是共享的主键关联,因此表中的外键同时Entity1
也是它的主键 Id
。
这意味着您的外键列已经被索引 - 即由 table 中的聚集主键索引Entity1
。
生成的 SQL 查询如下:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[OtherColumn] AS [OtherColumn]
FROM [dbo].[Entity2] AS [Extent1]
LEFT OUTER JOIN [dbo].[Entity1] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Entity1] AS [Extent3] ON [Extent2].[Id] = [Extent3].[Id]
WHERE [Extent3].[Id] IS NULL
如您所见,表由索引Id
列连接。第二个也是多余LEFT OUTER JOIN
的,是实体框架的 SQL 生成中的一个缺陷,它对 EF < 5.0 有效。我不确定它是否在 EF >= 5.0 中解决。我不知道这对查询性能是否真的很重要,因为该行通过同一列将表与自身连接起来,所以我希望 SQL 查询优化器能够识别它并忽略执行计划中的行。
本质上:您的 LINQ 查询很好,您无法提高性能,即使不向列添加任何附加索引也是如此。
但是,我建议找出真正慢的地方。它确实是 SQL 查询,还是从 LINQ 查询到 SQL 的转换,或者它可能是返回结果集的对象物化等?我要做的第一步是将生成的 SQL 查询粘贴到 SQL Server Management Studio 中,看看性能如何。即使您不会更改 LINQ 查询,也可能有其他机会来提高性能。
你说过
没有索引
但对于这个问题,那将是一个错误。索引几乎可以立即找到所有空引用。