SQL Server 2000:为什么这个带有/ variables的查询对w / o变量这么慢?

时间:2010-05-25 14:12:50

标签: sql sql-server tsql sql-server-2000

我无法弄清楚为什么这个查询在变量和没有变量时会如此慢。我读了一些我需要启用“动态参数”的地方,但我找不到在哪里这样做。

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

3 个答案:

答案 0 :(得分:7)

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

如果不是datetime,那么该列将转换为datetime,因为@ BeginDate / @ EndDate是datetime。这称为data type precedence。这包括列是否为smalldatetime(根据链接),因为datetime几乎具有最高优先级

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

转换意味着没有索引可以在计划中使用,这是原因。

查看查询计划后编辑

对于文字,SQL Server计算出搜索后跟书签查找是最好的,因为值是文字。

通常情况下,书签查找费用很高(顺便说一下,我们使用覆盖索引的原因之一)超过少数几行。

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

Simple-talk

上详细了解为什么书签查找通常是坏事

在这种情况下,您可以尝试使用索引提示强制它,但如果范围太宽则会非常慢。或者您可以删除SELECT *(无论如何都是错误的做法)并替换为SELECT col1, col2 etc并使用covering index

答案 1 :(得分:1)

SET STATISTICS IO ON
SET STATISTICS TIME ON

扫描次数和逻辑读数?

答案 2 :(得分:0)

您已经提到对不同服务器上相同数据的相同查询运行速度很快。

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

  • 处理器 - 相同的号码?
  • 是否有任何处理器超线程?
  • 磁盘的物理布局是否相同(磁盘速度,数据,日志,tempdb的单独主轴?)

此行为通常可以通过过时的统计信息来查看。

use dbfoo;
go
exec sp_updatestats
go

最后,比较每个框的SQL设置:

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