【问题标题】:Why is selecting date slow [duplicate]为什么选择日期很慢[重复]
【发布时间】:2015-05-12 01:12:25
【问题描述】:

我有一个包含大约 150 万行的表,其中 date_run 是非集群索引的。查询 #1 需要 0 秒才能完成,查询 #2 需要 3 秒。有人可以解释为什么查询 #2 运行速度较慢。我还包括了两者的执行计划。 Sql 服务器版本 2014。

查询 #1

select  avg14gain
from stocktrack
where 
date_run >=  '2013-3-21'
and date_run <  '2013-3-22'

Valid XHTML http://biginkz.com/Pics/DateHardCoded.jpg.

查询 #2

declare @today date
declare @yesterday date
set @today='2013-3-22'
set @yesterday='2013-3-21'
select avg14gain
from stocktrack
where 
date_run  >=   @yesterday
and b.date_run <@today

Valid XHTML http://biginkz.com/Pics/DataAsigned.jpg.

【问题讨论】:

  • b 中的 b.date_run 是什么?
  • 是的,但是为什么要进行表扫描呢? date_run 已编入索引。这两个查询实际上是相同的,只是 #1 是硬编码日期,而 #2 是分配的。
  • 这与改变基数估计的变量有关。 SQL 并不提前知道该变量是什么,因此它假设扫描表比进行查找和 RID 查找更有效。
  • 就@Zane而言,由于优化器在计划编译时不知道变量的值,因此它将依赖相关过滤器的密度向量值来满足第二个查询。在第一个查询中,优化器知道过滤器值,因此可以使用直方图生成估计值。它会根据这些估计来决定哪些操作最有效。
  • 感谢您详细说明@swasheck 尝试使用重新编译选项运行。

标签: sql-server date


【解决方案1】:

我不确定为什么您的查询没有获取索引,但您可以使用index hint

试试这样的:

declare @today date
declare @yesterday date
set @today='2013-3-22'
set @yesterday='2013-3-21'
select avg14gain
from stocktrack
where 
date_run  >=   @yesterday
and b.date_run <@today
with (index([stocktrack].[ix_drun])) 

您也可以尝试这篇文章中的建议:TSQL not using indexes。 请参阅@Justin Dearing 的回答(重建索引/更新统计信息)。

【讨论】:

  • 我不喜欢使用索引提示,因为索引可能会在以后更改并且如果更改会中断。
  • 我使用 with (index([stocktrack].[ix_drun])) 优化了查询。它更快,但由于执行计划中的排序,仍然需要 2 秒。我怎样才能摆脱这个执行计划中的排序?
  • 您也可以添加plan hint。在这一点上,我宁愿在索引上使用@pmbAustinINCLUDE columns 解决方案。
【解决方案2】:

在 date_run 上创建一个索引,并将 avg14gain 作为该索引上的一个 INCLUDE 列。这样一来,整个查询就可以从一个索引中得到满足,优化器会看到这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-02
    • 2011-03-30
    • 2021-10-31
    • 2010-10-21
    • 1970-01-01
    • 2013-11-18
    • 2014-08-14
    • 2019-10-02
    相关资源
    最近更新 更多