Sql Server 按偏移量分页行 - 没有'ORDER BY'
Posted
技术标签:
【中文标题】Sql Server 按偏移量分页行 - 没有\'ORDER BY\'【英文标题】:Sql Server paging rows by offset - without 'ORDER BY'Sql Server 按偏移量分页行 - 没有'ORDER BY' 【发布时间】:2009-10-31 15:28:39 【问题描述】:我的生产表包含超过一百万条记录。要求分页查询通过 OFFSET 和 LIMIT 参数检索记录(类似于 mysql 的 LIMIT 子句),而不对结果集进行排序,就像行的自然顺序在表扫描中一样,因为“ORDER BY”会产生不可接受的性能影响,包括传统技术 ROW_NUMBER() OVER (ORDER BY ...) 中使用的“ORDER BY”子句。 有哪位专家可以提供解决这个问题的方法吗?对结果集没有任何排序的分页记录。 例如
Create table RandomRecords(int id, datetime recordDate)
----
select * from RandomRecords
34, '1/1/2009'
123, '8/1/2008'
11, '2/23/2008'
10, '3/2/2008'
4, '2/5/2009'
78, '1/1/2008'
55, '5/2/2008'
6666, '2/12/2009'
....
one million rows
-----
paging query with @Offset = 3 and @limit=4 generates
11, '2/23/2008'
10, '3/2/2008'
4, '2/5/2009'
78, '1/1/2008'
【问题讨论】:
你能对你的表结构做更多解释吗?似乎您的 RandomRecords 表是您的情况的过于简单化的示例。 【参考方案1】:这只是对 Remus 回答的补充。
分页主键不会导致 SQL Server 排序,因为主键是按排序顺序存储的。您可以在没有 WITH 语句的情况下对主键进行分页,例如:
SELECT *
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY PrimaryKey) as rn
, *
FROM BigTable
) sub
WHERE sub.rn BETWEEN 3 and 7
子查询仍然是必需的,因为您不能在 WHERE 语句中使用 ROW_NUMBER()。
【讨论】:
【参考方案2】:ORDER BY 只有在无法通过索引解决时才会产生额外的影响。如果您看到“不可接受”的影响,则意味着您没有正确设计您的表,或者您没有正确设计查询。
一些我们不变的 ORDER BY 表达式SELECT ..., ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM ...
。但如果设计不当,仍可能会产生分拣线轴。
考虑一下你的例子:
CREATE TABLE RandomRecords (recordId int not null primary key, id int);
INSERT INTO RandomRecords (id) values (...)
WITH PagedRandomRecords (
SELECT id,
ROW_NUMBER() OVER (ORDER BY recordId) as rn
FROM RandomRecords)
SELECT id FROM PagedRandomRecords
WHERE rn BETWEEN 3 and 7;
这将不对数据进行排序,因为 recordId PK 聚集索引可以按所需顺序传递行。
【讨论】:
‒1 你是谁来确定什么是“不可接受的影响”【参考方案3】:如果您仍然找不到 ORDER BY 的列,您可以按添加的常量列进行排序,以使查询正常工作:
SELECT col1, col2 FROM
(SELECT col1, col2,
ROW_NUMBER() OVER (ORDER BY alias_sort) AS alias_rownum
FROM
(SELECT col1, col2, 0 AS alias_sort
FROM
(SELECT col1, col2
FROM ...)))
WHERE alias_rownum >= 12345 AND alias_rownum <= 67890
"0 AS alias_sort" 提供在父查询的 ORDER BY 子句中使用的常量列。顶部外部查询提供了过滤器并去掉了代理 alias_rownum 和 alias_sort 内部列。
【讨论】:
以上是关于Sql Server 按偏移量分页行 - 没有'ORDER BY'的主要内容,如果未能解决你的问题,请参考以下文章