Now, while the SQL transformation from
FETCH FIRST
toROW_NUMBER()
filtering is certainly correct, the execution plan doesn’t really make me happy. Consider theROWNUM
based query:--------------------------------------------------------- | Id | Operation | Name | Rows | --------------------------------------------------------- | 0 | SELECT STATEMENT | | | |* 1 | COUNT STOPKEY | | | | 2 | VIEW | | 1 | | 3 | TABLE ACCESS BY INDEX ROWID| FILM | 1000 | | 4 | INDEX FULL SCAN | PK_FILM | 1 | --------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(ROWNUM=1)And compare that to the
FETCH FIRST
query:------------------------------------------------- | Id | Operation | Name | Rows | ------------------------------------------------- | 0 | SELECT STATEMENT | | | |* 1 | VIEW | | 1 | |* 2 | WINDOW SORT PUSHED RANK| | 1000 | | 3 | TABLE ACCESS FULL | FILM | 1000 | ------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=1) 2 - filter(ROW_NUMBER() OVER ( ORDER BY "FILM"."FILM_ID")<=1)
Lukas digs into this and is not the biggest fan of OFFSET-FETCH. On the SQL Server side, my anecdotal experience has been that it doesn’t perform nearly as well as you’d like either.