SQL Server - JOIN未使用Entity Framework生成的查询

时间:2015-07-22 11:31:46

标签: sql-server performance entity-framework database-performance

我正在使用Entity Framework在我的数据库上执行相当复杂的查询。该查询包含其他几个.Union()的{​​{1}}。

为了优化所述查询,我​​已经分解了不同的子查询并单独测试它们以测量性能,并发现其中一个(让我们称之为IQueryables)比其他

joinRes是两个(已过滤)表之间的连接,其中一个表具有大量记录,而另一个表只有几个。

joinRes

查看SQL Server中的实际执行计划,我可以看到var smallDataSet = RepositoryForSmallDataSet.Where(smDs => ... ); var joinRes = smallDataSet.Join(largeDataSet, smDs => smDs.SomeID, bigDs => bigDs.SomeID, (smDs, bigDs) => bigDs) .OrderByDescending(bigDs => bigDs.SomeDate); // ... IQueryable joinRes will be used in some .Union() operations with other IQueryables into a largeQuery IQueryable... var result = largeQuery.Take(10).ToList(); 子查询中的Nested Loops步骤没有选择最佳顺序(joinRes首先smallDataSet }})。如果我向生成的SQL添加largeDataSet提示,则子查询要快得多。

SQL Server Execution Plan join

问题是我似乎找不到通过Entity Framework添加该提示的方法,只需将复杂查询(请记住OPTION (FORCE ORDER)是大型复杂查询的一部分)移动到存储过程中将是一个主要的麻烦(它是一个动态生成的大量查询,它可能需要大量的动态SQL)。

有关如何解决此问题的任何建议?

编辑:

Evaldas Buinauskas用他的回答让我走上正轨。 Poor performance was caused by Key Lookup以及由TPT继承机制引起的一堆其他JOINS(本问题中未提及)。修复了索引(基于SQL Server的执行计划)和重构的继承,以改为使用TPH方法。

1 个答案:

答案 0 :(得分:2)

你的索引是对的吗?由于Key Lookup表示您的索引不包含加入条件,或者它输出了未包含在索引中的列。

建议消除它们(查找)。这是very detailed article解释如何执行此操作。

  

当您对表进行索引查找时会发生键查找,但是   您的查询需要不在该索引中的其他列。   这会导致SQL Server必须返回并检索这些额外的内容   列。