Far*_*ruz 7 sql t-sql sql-server
我从SQL Server(2005)得到了一个奇怪的执行计划行为.
TableName:LOG
...包含大约1000行
查询:
SELECT *
FROM (SELECT ROW_NUMBER() OVER (ORDER BY ID DESC) as Row,
ID, Name
FROM Log) AS LogWithRowNumbers
WHERE Row >= 1
AND Row <= 2
Run Code Online (Sandbox Code Playgroud)
它估计返回的行数为9(虽然它明显为2或更少).
此外,删除"和行<= 2"将使执行时间增加约*5.("和行<= 2"和"和行<= 9999999999999"表现相同)
我已经更新了统计数据.但是,这种行为很奇怪.添加行<99999999999将使查询运行得更快?为什么?
我不是SQL Server内部工作/查询优化过程的专家,但这是我的2便士(如果你愿意的话,还是美分).
我相信这是由于在WHERE子句中使用了ROW_NUMBER()值.作为一个例子,我创建了一个样本表,填充了从ID 1到1000的1000行(ID作为主键),就像你说的那样.
如果您取出ROW_NUMBER(),并根据ID列执行查询,如下所示:
Select * FROM
(
SELECT ID, Name
FROM Log
)
as LogWithRowNumbers
WHERE ID>=1 and ID<=2
Run Code Online (Sandbox Code Playgroud)
然后它正确显示行数为2 - 正如预期的那样.
现在,向后工作,将ROW_NUMBER添加到内部SELECT,但保留WHERE子句,如下所示:
Select * FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY ID DESC) AS RowNo,
ID, Name
FROM Log
)
as LogWithRowNumbers
WHERE ID>=1 AND ID <=2
Run Code Online (Sandbox Code Playgroud)
这仍然显示正确的行数为2.
最后,将WHERE子句设置回来使用RowNo作为要过滤的列而不是ID,这是估计行数跳到9时的情况.
因此,我相信它是使用ROW_NUMBER()函数,在WHERE子句中被过滤,这是原因.所以我想这是因为实际表列上有明显更好/更准确的统计信息,而不是这个函数产生的值.
我希望这至少提供了一个很好的起点,希望有用!
| 归档时间: |
|
| 查看次数: |
2625 次 |
| 最近记录: |