まず、内部クエリはどのような順序付けも行っていないため、クエリは任意の100行を返します。これが結果をページングするクエリを作成しようとしている場合、これは効率的ではなく、正しくないため、適切なアプローチではありません。返される行のセットは時間の経過とともに変化する可能性があり、行は結果の多くの異なるページに簡単に表示されるか、ページがまったく表示されません。
ただし、クエリプランを確認することで、フィルタがいつ適用されるかを確認するのは簡単です。FOO
100,000行の簡単なテーブルを作成します
SQL> drop table foo;
Table dropped.
SQL> create table foo
2 as
3 select level col1
4 from dual
5 connect by level <= 100000;
Table created.
次に、自動トレースを有効にし、実際のデータの表示を抑制して、クエリを実行します
SQL> set autotrace traceonly;
SQL> select *
2 from (select rownum rn, col1
3 from foo)
4 where rn between 1 and 100;
100 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3193632835
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 101K| 2577K| 47 (3)| 00:00:01 |
|* 1 | VIEW | | 101K| 2577K| 47 (3)| 00:00:01 |
| 2 | COUNT | | | | | |
| 3 | TABLE ACCESS FULL| FOO | 101K| 1288K| 47 (3)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RN"<=100 AND "RN">=1)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
164 consistent gets
0 physical reads
0 redo size
2504 bytes sent via SQL*Net to client
590 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
100 rows processed
クエリプランを見ると、述語FOO
を適用する前に全表スキャンを実行したことがわかります。rn between 1 and 100
そのため、結果セット全体が具体化されました(一貫した取得の数は、おおよそテーブル内のブロックの数です)。
より適切なページ付けクエリを使用した場合(たとえば、 TomKyteがページ付けに関するOracleMagazineの記事を掲載し、askTomでページ付けについてさらに長い議論を行っている場合)、クエリプランSORT ORDER BY STOPKEY
に、Oracleが停止できることを認識していることを示す何かが表示されます。ある時点以降の処理。