I’ve run across a strange situation regarding a paginated query and the stopkey optimization on 11G (I’ve been able to reproduce on full 11G as well as XE installs). I’m using the alexa top 1M sites for a test database with (id, url, page) as columns and the id column indexed. The following query:
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;
Generates this execution plan:

While this 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;
Generated an execution plan with the STOPKEY optimization:

The only difference between the two is WHERE raw_rnum_ between 800001 and 800010;
vs WHERE raw_rnum_ >= 800001 and rownum <= 10.
From what I can see these queries behave exactly the same otherwise. Does anyone know why the stopkey optimization is missing from the first query?
I wouldn’t think of it as of a bug.
I would assume that optimizer is unable to push your
raw_rnum_ between 800001 and 800010deeper into subquery, as it would result inwhere rownum >800001 and rownum < 800010, which obviously doesn’t make any sense.So it treats your
raw_rnum_as a plain number column, probably unable to assume that initial predicate onraw_rnum_would filter out only 10 rows.