【发布时间】:2011-09-05 09:17:08
【问题描述】:
我正在使用 EntityFramework 4 访问 SQL Server 2008 数据库。
EF 生成的 SQL 查询之一具有我无法解释的行为。 查询是这样的:
SELECT tableA.field1, tableA.field2, ...
FROM tableA join tableB on tableA.field1 = tableB.field1
WHERE
tableA.field2 > '20110825'
and tableA.field3 in ('a', 'b', 'c,')
and tableB.field4 = 'xxx'
其中tableA.field2 为datetime not null,其他字段为varchars。
tableA 包含大约 150 万条记录,tableB 包含大约 200 万条记录,查询返回 1877 行。
问题是,它会在 86 秒内返回它们,而当我将 '20110825' 文字更改为旧值时,该时间会发生巨大变化。
例如,如果我输入“20110725”,查询会在 35 毫秒内返回 3483 行。
我在执行计划中发现,两者的区别在于SQL Server根据用于比较的日期选择使用的索引。
当需要时间时,执行计划显示:
- 50%:在 tableA.field2 上进行索引查找(仅此字段上的聚集索引)
- 50%:在 tableB.field1 上查找索引(仅此字段上的非唯一、非聚集索引)
- 0%:加入
当几乎是瞬间的时候,执行计划显示:
- 98%:在 tableA.field1 上查找索引(仅此字段上的非唯一、非聚集索引)
- 2%:tableB.field1 上的索引查找(仅此字段上的非唯一、非聚集索引)
- 0%:加入
所以在我看来,优化器在 tableA.field2 上使用聚集索引的决定并不是最优的。
数据库设计是否存在缺陷?在 SQL 查询中?
我可以以任何方式强制数据库使用正确的执行计划吗?
【问题讨论】:
标签: c# sql-server sql-server-2008 entity-framework .net-4.0