【问题标题】:Entity Framework 4: How to enforce WHERE clause order in generated query实体框架 4:如何在生成的查询中强制执行 WHERE 子句顺序
【发布时间】:2011-01-19 10:14:59
【问题描述】:

假设下表MyObjects

Id (PK, int)
DecimalField (decimal)
TextField (nvarchar)

我在DecimalField 上添加了一个附加索引。

考虑以下 LINQ to Entities 查询来检索对象:

db.MyObjects.FirstOrDefault(r => r.DecimalField == localValue1 && r.TextField == localValue2)

因为有索引,所以 EF 生成的查询必须保持 WHERE 子句中属性的顺序相同(即DecimalField 第一和TextField 第二),否则会发生表扫描并且索引没用。如何强制 EF 在 WHERE 子句中保持一定的顺序?即席查询和编译查询之间有区别吗?

【问题讨论】:

  • KristoferA 的回答是正确的。为了向自己证明这一点,请在 Management Studio 中编写两个 SQL 查询,打开“实际执行计划”,然后运行查询。如果这两个查询没有得到完全相同的计划,那么某处就出现了严重问题。

标签: c# sql-server entity-framework linq-to-entities


【解决方案1】:

不,where 子句谓词的顺序无关紧要。如果有一个索引,SQL Server 将使用适当的索引,即使您的 where 子句指定列的顺序与它们在索引中出现的顺序不同。

【讨论】:

  • 是的,绝对确定。如果 SQL Server 决定使用索引,则原因完全不同。例如。在创建索引之前生成的缓存执行计划*、索引的过时统计信息,或者可以在不使用索引的情况下更有效地执行的查询。 * = 虽然在创建新索引时应该放弃该计划,但有时还是需要 sp_recompile 或 dbcc freeproccache。
  • 听起来不错,至少对于 SQL Server 2005+ 而言。但我过去在使用 SQL Server 2000 时遇到过问题。
  • 即使在 SQL 2000 下,也很可能是由“错误”的缓存执行计划引起的。更改顺序只是强制 SQL Server 将其视为新查询并再次编译它,如果运气好的话,新计划会更好(由于更新的统计信息,或者 SQL Server 有足够的资源来评估更多计划选项*,或者...)。 * = 高负载下的服务器更有可能为复杂查询制定糟糕的计划,因为优化器将有更少的时间和资源来选择计划。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多