0

我遇到了一些性能问题。我得到了以下数据库模型。 模型

我希望选择 Entity2 中所有在 Entity1 中没有外键的条目,换句话说,导航属性必须为空。

我提出了以下 LINQ 查询context.Entity2Set.Where(x => x.Entity1 == null);,它可以工作,但是速度很慢。所以我想知道是否有更好(更快)的方式(除了索引)来选择条目。

最后我想从Entity4中选择条目,所以性能是一个问题。

4

2 回答 2

2

您正在查询关系 ( 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 查询,也可能有其他机会来提高性能。

于 2013-02-17T16:15:07.293 回答
0

你说过

没有索引

但对于这个问题,那将是一个错误。索引几乎可以立即找到所有空引用。

于 2013-02-17T15:17:29.340 回答