我在表格中有440行与我的以下查询匹配
SELECT RecordID
FROM
[tblRules]
WHERE
DATEDIFF(MONTH,CreationDate,GETDATE()) >= 6
AND YEAR(CreationDate) = 2013
ORDER BY RecordID , BR_ID
当我执行此查询时,我在4秒内得到440行
当我像下面那样做顶部时,
SELECT TOP 440 RecordID
FROM
[tblRules]
WHERE
DATEDIFF(MONTH,CreationDate,GETDATE()) >= 6
AND YEAR(CreationDate) = 2013
ORDER BY RecordID , BR_ID
它在7秒内返回440行
但是当我设置高位数然后它永远运行而不返回结果我给它一个完整的运行时它运行直到服务器的内存缓冲区已满5小时我运行的查询是
SELECT TOP 500 RecordID
FROM
[tblRules]
WHERE
DATEDIFF(MONTH,CreationDate,GETDATE()) >= 6
AND YEAR(CreationDate) = 2013
ORDER BY RecordID , BR_ID
即使我用500
以外的任何内容替换440
,它也会继续运行并且永远不会返回结果。我挣扎着退出很多,任何人都可以给我任何解决方案或理由,为什么会发生这种情况。该数据库中的所有其他表都正常工作。表tblRules
中有超过10亿条记录。
答案 0 :(得分:3)
我的第一个观察是where子句中使用的函数。这将阻止优化器在CreationDate上使用任何可用的索引。
要使优化器能够有效地使用索引,查询应该是SARGable
What makes a SQL statement sargable?
declare @yeartoget varchar(4)='2013'
SELECT TOP 440 RecordID
FROM
[tblRules]
WHERE
CreationDate >= DATEADD(MONTH,-6 ,getdate())
AND CreationDate
between convert(datetime,convert(varchar(4),@yeartoget)+'0101') and
convert(datetime,convert(varchar(4),@yeartoget)+'1231')
ORDER BY RecordID , BR_ID
这个版本有什么不同吗?