Oracle
 sql >> Database >  >> RDS >> Oracle

Perché Oracle SQL Optimizer ignora il predicato dell'indice per questa vista?

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)