Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql server:估计的行数相差很远_Sql_Sql Server_Tsql - Fatal编程技术网

sql server:估计的行数相差很远

sql server:估计的行数相差很远,sql,sql-server,tsql,Sql,Sql Server,Tsql,我从SQLServer2005中得到了一个奇怪的执行计划行为 表名:LOG …包含大约1000行 ID int 名称varchar50 查询: SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY ID DESC) as Row, ID, Name FROM Log) AS LogWithRowNumbers WHERE Row >= 1 AND Row <= 2 它估计

我从SQLServer2005中得到了一个奇怪的执行计划行为

表名:LOG …包含大约1000行

ID int 名称varchar50 查询:

SELECT * 
  FROM (SELECT ROW_NUMBER() OVER (ORDER BY ID DESC) as Row,
               ID, Name
          FROM Log) AS LogWithRowNumbers
 WHERE Row >= 1 
   AND Row <= 2
它估计返回的行数为9,虽然很明显是2或更少。
另外,删除and行我对SQL Server的内部工作/查询优化过程不是专家,但如果您愿意,这里是我的2便士或2美分

我相信这是由于WHERE子句中使用了ROW_NUMBER值。例如,我创建了一个示例表,其中填充了1000行,从ID 1到1000 ID,作为主键,如您所说

如果您取出行号,并根据ID列进行如下查询:

Select * FROM
(
 SELECT ID, Name
 FROM Log
)
as LogWithRowNumbers
WHERE ID>=1 and ID<=2
然后,它正确地将行数显示为2—正如预期的那样

现在,向后操作,将行号添加到内部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
这仍然将正确的行计数显示为2

最后,将WHERE子句设置回使用RowNo作为要筛选的列,而不是ID,此时估计的行数跳到9

因此,我认为是由于使用了ROW_NUMBER函数,在WHERE子句中进行了过滤。所以我认为这是因为,与此函数生成的值相比,在实际表列上明显有更好/更准确的统计信息


我希望这至少提供了一个良好的起点,希望将是有用的

AdaTheDev是正确的。您看到这种行为的原因是,SQL Server必须先计算出表的行号,然后才能在where子句中使用它们

这应该是获得相同结果的更有效的方法:

 SELECT TOP(2) ROW_NUMBER() OVER (ORDER BY ID DESC) as Row,
 ID, Name
 FROM Log
 ORDER BY ID DESC

伙计们,这很容易复制。当你需要DBA天才时,他们在哪里???@Faruz:我不是DBA。但是,如果只有一个条件而没有任何AND/OR,即ROW=1,那么查询的执行速度会更快吗。当ROW=1或ROW=2时,与使用>=和ROW=1或ROW=2时相比,它是如何执行的。。。它不创建内部索引,而是使用PK索引ID。我明白你的意思,只是这是我查询的一个示例。我通常检索第1-10行、第10-20行等。问题是,我必须在没有该行的情况下进行检索