SQL Server 2000中:为什么这个查询W /变量如此缓慢VS W / O变量?(SQL S

2019-09-30 08:28发布

我想不通,为什么这个查询将与变量对没有他们这么慢。 我读了一些在那里,我需要启用“动态参数”,但我找不到在哪里做到这一点。

DECLARE
      @BeginDate AS DATETIME
     ,@EndDate AS DATETIME
SELECT
      @BeginDate = '2010-05-20'
     ,@EndDate = '2010-05-25'

-- Fix date range to include time values
SET @BeginDate = CONVERT(VARCHAR(10), ISNULL(@BeginDate, '01/01/1990'), 101) + ' 00:00'
SET @EndDate = CONVERT(VARCHAR(10), ISNULL(@EndDate, '12/31/2099'), 101) + ' 23:59'

SELECT
     *
FROM
    claim c
WHERE
    (c.Received_Date BETWEEN @BeginDate AND @EndDate) --this is much slower
    --(c.Received_Date BETWEEN '2010-05-20' AND '2010-05-25') --this is much faster

Answer 1:

什么数据类型是“c.Received_Date”?

如果不是日期时间则因为@ BEGINDATE / @结束日期日期时间是该列将被转换为日期时间。 这就是所谓的数据类型的优先级 。 这包括如果该列是SMALLDATETIME(按链接),因为日期时间几乎最高的优先级

与常量,优化器将使用列数据类型

转换装置没有索引寻道可以在计划,这是原因被使用。

编辑,看到查询计划后

对于文字,SQL Server将摸索出了一个寻求其次书签查找是最好的,因为值是文字。

一般情况下,(为什么我们使用了覆盖索引和偶然的原因之一)超过一把行书签查找是昂贵的。

对于使用变量的查询时,它采取了一般的情况下,因为如果值的变化可以重复使用计划。 一般情况下是可以避免的书签查找,在这种情况下,你有一个PK(聚集索引)扫描

详细了解为何书签查找通常是在一个糟糕的事情 简单的对话

在这种情况下,你可以尝试一个索引提示来强制,但如果范围太广这将是很慢。 或者你可以删除SELECT * (不好的做法,反正),并通过替换SELECT col1, col2 etc ,并使用覆盖索引



Answer 2:

SET STATISTICS IO ON
SET STATISTICS TIME ON

扫描次数和逻辑读取?



Answer 3:

你已经提到,在不同的服务器上相同的数据相同的查询跑得快。

是硬件相同,或至少相当类似?

  • 处理器 - 同样数量?
  • 任何处理器使用超线程技术?
  • 是磁盘相同的物理布局(磁盘速度,数据独立的轴上,日志,tempdb的?)

这种行为通常可以通过过时的统计数据中可以看出。

use dbfoo;
go
exec sp_updatestats
go

最后,比较每只箱子SQL设置:

exec sp_configure 'show advanced options', '1'
go
RECONFIGURE
exec sp_configure;
go


文章来源: SQL Server 2000: Why is this query w/ variables so slow vs w/o variables?