Oracle tidak menggunakan indeks karena mengasumsikan select column_value from table(x)
mengembalikan 8168 baris.
Indeks lebih cepat untuk mengambil sejumlah kecil data. Pada titik tertentu, memindai seluruh tabel lebih cepat daripada menelusuri pohon indeks berulang kali.
Memperkirakan kardinalitas pernyataan SQL biasa cukup sulit. Membuat perkiraan yang akurat untuk kode prosedural hampir tidak mungkin. Tapi saya tidak tahu di mana mereka menemukan 8168. Fungsi tabel biasanya digunakan dengan fungsi pipelined di gudang data, jumlah yang agak besar masuk akal.
Pengambilan sampel dinamis dapat menghasilkan perkiraan yang lebih akurat dan kemungkinan menghasilkan rencana yang akan menggunakan indeks.
Berikut ini contoh perkiraan kardinalitas yang buruk:
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 |
-------------------------------------------------------------------------
Berikut cara memperbaikinya:
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)