Bil*_*l D 1 sql t-sql sql-server 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
Run Code Online (Sandbox Code Playgroud)
什么数据类型是"c.Received_Date"?
如果它不是datetime,那么该列将转换为datetime,因为@ BeginDate/@ EndDate是datetime.这称为数据类型优先级.这包括列是否为smalldatetime(根据链接),因为datetime几乎具有最高优先级
对于常量,优化器将使用列数据类型
转换意味着没有索引可以在计划中使用,这是原因.
在查看查询计划后编辑
对于文字,SQL Server计算出搜索后跟书签查找是最好的,因为值是文字.
通常,书签查找是昂贵的(并且顺便说一下我们使用覆盖索引的一个原因)超过少数几行.
对于使用变量的查询,它采用了一般情况,因为如果值更改,则可以重用计划.一般情况是避免书签查找,在这种情况下,您有一个PK(聚簇索引)扫描
阅读更多关于为什么书签查找在Simple-talk上通常是一件坏事的原因
在这种情况下,您可以尝试使用索引提示强制它,但如果范围太宽则会非常慢.或者你可以删除SELECT *
(反正的不良做法)并替换SELECT col1, col2 etc
并使用覆盖索引
归档时间: |
|
查看次数: |
933 次 |
最近记录: |