包装在分页选择语句和 ROWNUM 中的子查询的行为
Posted
技术标签:
【中文标题】包装在分页选择语句和 ROWNUM 中的子查询的行为【英文标题】:Behaviour of sub query wrapped in a pagination select statement and ROWNUM 【发布时间】:2013-03-01 17:55:07 【问题描述】:我在少数情况下使用了以下“wapper”来实现分页,并且通常将其称为“标准分页选择”。 因此,要对任何 select 语句的结果进行分页,只需将 select 语句包装在“标准分页选择”中即可。
SELECT * FROM (SELECT a.*, ROWNUM rnum FROM ((
( subquery: put your select * from ....... here ..)
)) a WHERE ROWNUM <= $resultEnd )
WHERE rnum >= $resultStart
我的问题是关于分页位的行为和 ROWNUM 周围的魔法。据我了解,子查询不每次都选择完整的结果集,并且是 寻找确认或其他方式?
以下是对上面显示的分页行为的正确描述,例如如果页面大小为 50:
选择:
第 1 页(例如 0-50)子查询选择 0-50 行 第 2 页(例如 51-100)子查询选择 0-100 行(外部查询然后将其限制为 50-100) 第 3 页(例如 101-150)子查询选择 0-150 行(外部查询将其限制为 101-150) 第 4 页(例如 151-200)子查询选择 0-200 行(外部查询然后将其限制为 151-200) 第 5 页(例如 201-250)子查询选择 0-250 行(外部查询然后将其限制为 201-250)...等等,你可以看到图案。
您越深入“页面”,子查询要做的工作就越多。它是否正确?如果是这样,ROWNUM 如何做到这一点?
提前致谢。并反馈赞赏
【问题讨论】:
好 tom kyte 文章:oracle.com/technetwork/issue-archive/2007/07-jan/… 【参考方案1】:如果查询被很好地索引并且执行得很好,为什么不尝试使用物化视图呢? 您可以将 rownum 定义为列并按需刷新视图。 也请注意。Oracle 12C 即将提供对分页类型查询的出色支持。
【讨论】:
【参考方案2】:您的理解通常是正确的。内部 rownum <= end
将在生成 end
行后“中断”内部查询,而外部 rownum >= start
丢弃第一行。
rownum
是动态生成的,优化器知道rownum <
过滤器,因此它可以影响行源并停止它(在解释计划中查找COUNT STOPKEY
行,这就是您将要做的看看它是否有效)。
但不能保证内部选择会停止。特别是,其中的order by
子句可能会强制生成整个结果集,然后rownum
过滤器会简单地丢弃该间隔之外生成的行。
【讨论】:
以上是关于包装在分页选择语句和 ROWNUM 中的子查询的行为的主要内容,如果未能解决你的问题,请参考以下文章
pageHelper分页查询oracle数据插入mysql时数据量变少
关于SQL的over partition by 开窗语句在分页和统计中的使用总