Sql Oracle-为什么此分页代码不使用stopkey优化

Sql Oracle-为什么此分页代码不使用stopkey优化,sql,oracle,oracle11g,sql-execution-plan,Sql,Oracle,Oracle11g,Sql Execution Plan,我遇到了一个奇怪的情况,关于分页查询和11G上的stopkey优化,我已经能够在完整的11G和XE安装上重现。我使用alexa top 1M站点作为测试数据库,id、url、page作为列,id列被索引。以下查询: SELECT * FROM ( SELECT raw_sql_.*, rownum raw_rnum_ FROM (select id, url, page from alexa_data order by id asc) raw_sql_ ) WHERE raw_rnum_

我遇到了一个奇怪的情况,关于分页查询和11G上的stopkey优化,我已经能够在完整的11G和XE安装上重现。我使用alexa top 1M站点作为测试数据库,id、url、page作为列,id列被索引。以下查询:

SELECT * FROM (
  SELECT raw_sql_.*, rownum raw_rnum_
  FROM (select id, url, page from alexa_data order by id asc) raw_sql_
)
WHERE raw_rnum_ between 800001 and 800010;
生成此执行计划:

而此SQL:

SELECT * FROM (
  SELECT raw_sql_.*, rownum raw_rnum_
  FROM (select id, url, page from alexa_data order by id asc) raw_sql_
)
WHERE raw_rnum_ >= 800001 and rownum <= 10;
使用停止键优化生成执行计划:

两者之间的唯一区别是,原始值介于800001和800010之间;
我不认为它是一个bug

我假设优化器无法将800001到800010之间的原始值进一步推到子查询中,因为这将导致rownum>800001和rownum<800010,这没有任何意义


因此,它将您的raw\u rnum\u视为一个普通的数字列,可能无法假设raw\u rnum\u上的初始谓词只过滤出10行。

我不认为它是一个bug

我假设优化器无法将800001到800010之间的原始值进一步推到子查询中,因为这将导致rownum>800001和rownum<800010,这没有任何意义


因此,它将您的raw_rnum_视为一个普通数字列,可能无法假设raw_rnum_上的初始谓词将只过滤掉10行。

我同意,我在提交后重新阅读文章时实际上编辑掉了bug一词=我同意,我在提交后重新阅读文章时实际上编辑掉了bug一词=