sql server:估计的行数是关闭的

Far*_*ruz 7 sql t-sql sql-server

我从SQL Server(2005)得到了一个奇怪的执行计划行为.

TableName:LOG
...包含大约1000行

  • ID int
  • 名称varchar(50)

查询:

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将使查询运行得更快?为什么?

Ada*_*Dev 6

我不是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子句中被过滤,这是原因.所以我想这是因为实际表列上有明显更好/更准确的统计信息,而不是这个函数产生的值.

我希望这至少提供了一个很好的起点,希望有用!