【问题标题】:SELECT with "datetime > string" performance issue in EF4 / SQL Server 2008在 EF4/SQL Server 2008 中选择“日期时间 > 字符串”性能问题
【发布时间】: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


    【解决方案1】:

    鉴于您使用的是文字值并且只遇到最近日期字符串的问题,我怀疑您遇到了问题described here 并且需要安排工作来更新您的统计信息。

    据推测,当它们最后一次更新时,很少或没有符合 '20110825' 标准的行,并且 SQL Server 正在使用基于该假设的连接策略。

    【讨论】:

    • 是的,就是这个想法。由于缺少统计信息更新,SQL 优化器错误地使用了基于日期的索引。由于数据库是我商店业务的核心,我会建议他们考虑每日更新工作的想法,但同时,我将通过在两者上调用 WITH INDEX 来强制使用“正确”的索引表。
    猜你喜欢
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 2016-11-29
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    相关资源
    最近更新 更多