包装在分页选择语句和 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 &lt;= end 将在生成 end 行后“中断”内部查询,而外部 rownum &gt;= start 丢弃第一行。

rownum 是动态生成的,优化器知道rownum &lt; 过滤器,因此它可以影响行源并停止它(在解释计划中查找COUNT STOPKEY 行,这就是您将要做的看看它是否有效)。

但不能保证内部选择会停止。特别是,其中的order by 子句可能会强制生成整个结果集,然后rownum 过滤器会简单地丢弃该间隔之外生成的行。

【讨论】:

以上是关于包装在分页选择语句和 ROWNUM 中的子查询的行为的主要内容,如果未能解决你的问题,请参考以下文章

pageHelper分页查询oracle数据插入mysql时数据量变少

Oracle 分页查询rownum的用法

大数据oracle分页查询

关于SQL的over partition by 开窗语句在分页和统计中的使用总

oracle分页查询,一个select语句解决,不需要子查询。

Java中oracle分页查询01