当按高行数过滤时,SQL存储过程运行速度极慢

时间:2012-11-02 20:00:08

标签: sql performance stored-procedures

此查询是从一个非常长的动态续集存储过程生成的 - 该过程返回从给定索引开始的请求数量的记录,以便在Telerik Radgrid中显示,从而有效地处理分页。存储过程输出的简化版本:

SELECT r.* FROM (
       SELECT ROW_NUMBER() OVER(ORDER BY InventoryId DESC) as row,
       v.* FROM vInventorySearch v
       ) as R WHERE [ROW] BETWEEN 1 AND 10

当“BETWEEN”子句介于1和10之间时,它会在几分之一秒内运行,但如果它介于10000和1010之间,则需要几乎整整一分钟才能执行。

我觉得我可能会遗漏一些基本的东西,但在我看来,我正在检索哪10条记录并不重要,它应该花费相同的时间。

感谢您的任何意见,我期待着感到尴尬!


解决方案,马丁史密斯(下图)提供:

SELECT r.*, inv.* FROM 
(
    SELECT ROW_NUMBER() OVER(ORDER BY InventoryId DESC) as row, v.InventoryID
    FROM vInventorySearch v
    WHERE 1=1 
) as R 
inner join vInventory inv on r.InventoryID = inv.InventoryID
WHERE [ROW] BETWEEN 10001 AND 10010

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

ROW_NUMBER的分页对于更高的行数确实非常低效。

有时最好稍微分解一下并在窄索引上进行ROW_NUMBER查询以检索匹配的PK,并将连接返回到基表上以检索缺少的列。

答案 1 :(得分:1)

SQL 2012具有更高效的分页机制

http://stevestedman.com/2012/04/tsql-2012-offset-and-fetch/

SELECT DepartmentID,Revenue,Year 来自收入 按年份订购,DepartmentID ASC OFFSET 10 ROWS FETCH NEXT 10行;