【问题标题】:SQL stored proc runs extremely slow when filtering by high row numbers当按高行数过滤时,SQL 存储过程运行速度极慢
【发布时间】:2012-11-02 20:00:07
【问题描述】:

这个查询是从一个非常长的动态后续存储过程生成的——该过程返回从给定索引开始的请求记录数,以显示在 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 条记录并不重要,它应该花费相同的时间。

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


解决方案,由 Martin Smith(下)提供:

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

感谢您的帮助!

【问题讨论】:

  • 你能发布你的表定义,包括索引和执行计划吗?

标签: sql performance stored-procedures


【解决方案1】:

ROW_NUMBER 分页对于更高的行数确实效率很低。

有时最好将其拆分一下并在窄索引上使用 ROW_NUMBER 查询以检索匹配的 PK,并将连接返回到基表以检索丢失的列。

【讨论】:

  • 非常感谢,马丁。这正是我最终所做的……查询从 45 秒缩短到了几分之一秒。帖子中的解决方案。
  • @DanielMyManiel - 很高兴它有帮助。我已经看到ROW_NUMBER 计划在其中进行数千次不必要的书签查找以检索实际上永远不会被使用的列值,因为它们只需要与过滤器匹配的 10 行左右。我想在你的情况下vInventorySearch 可能是一个视图,所以它可能正在执行更昂贵的操作。
【解决方案2】:

SQL 2012 有更高效的分页机制

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

选择部门 ID、收入、年份 从收入 ORDER BY Year, DepartmentID ASC 偏移 10 行仅获取下 10 行;

【讨论】:

  • 谢谢你,我得去看看。现在我正在使用 SQL 2008,但在下一个项目中会记住这一点。
猜你喜欢
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
相关资源
最近更新 更多