Oracle non utilizza l'indice perché presuppone select column_value from table(x)
restituisce 8168 righe.
Gli indici sono più veloci per il recupero di piccole quantità di dati. Ad un certo punto è più veloce scansionare l'intera tabella che percorrere ripetutamente l'albero degli indici.
La stima della cardinalità di una normale istruzione SQL è già abbastanza difficile. Creare una stima accurata per il codice procedurale è quasi impossibile. Ma non so dove siano arrivati a 8168. Le funzioni di tabella sono normalmente utilizzate con le funzioni pipeline nei data warehouse, un numero abbastanza grande ha senso.
Campionamento dinamico può generare una stima più accurata e probabilmente generare un piano che utilizzerà l'indice.
Ecco un esempio di una cattiva stima della cardinalità:
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 |
-------------------------------------------------------------------------
Ecco come risolverlo:
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)