Oracleは、select column_value from table(x)
を想定しているため、インデックスを使用しません。 8168行を返します。
インデックスは、少量のデータを取得する場合に高速です。ある時点で、インデックスツリーを繰り返し歩くよりも、テーブル全体をスキャンする方が高速です。
通常のSQLステートメントのカーディナリティを推定することは十分に困難です。手続き型コードの正確な見積もりを作成することはほとんど不可能です。しかし、彼らが8168をどこで思いついたのかはわかりません。テーブル関数は通常、データウェアハウスのパイプライン関数で使用されるため、かなりの数が理にかなっています。
動的サンプリング より正確な見積もりを生成し、インデックスを使用する計画を生成する可能性があります。
カーディナリティの見積もりが悪い例を次に示します。
create or replace type type_table_of_number as table of number;
explain plan for
select * from table(type_table_of_number(1,2,3,4,5,6,7));
select * from table(dbms_xplan.display(format => '-cost -bytes'));
Plan hash value: 1748000095
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Time |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8168 | 00:00:01 |
| 1 | COLLECTION ITERATOR CONSTRUCTOR FETCH| | 8168 | 00:00:01 |
-------------------------------------------------------------------------
修正方法は次のとおりです。
explain plan for select /*+ dynamic_sampling(2) */ *
from table(type_table_of_number(1,2,3,4,5,6,7));
select * from table(dbms_xplan.display(format => '-cost -bytes'));
Plan hash value: 1748000095
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Time |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 7 | 00:00:01 |
| 1 | COLLECTION ITERATOR CONSTRUCTOR FETCH| | 7 | 00:00:01 |
-------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)