Oracle
 sql >> Base de données >  >> RDS >> Oracle

Pourquoi Oracle SQL Optimizer ignore-t-il le prédicat d'index pour cette vue ?

Oracle n'utilise pas l'index car il suppose select column_value from table(x) renvoie 8168 lignes.

Les index sont plus rapides pour récupérer de petites quantités de données. À un moment donné, il est plus rapide de parcourir toute la table que de parcourir l'arborescence de l'index de manière répétée.

L'estimation de la cardinalité d'une instruction SQL régulière est déjà assez difficile. Créer une estimation précise pour le code procédural est presque impossible. Mais je ne sais pas d'où ils sont venus avec 8168. Les fonctions de table sont normalement utilisées avec des fonctions en pipeline dans les entrepôts de données, un nombre assez grand a du sens.

Échantillonnage dynamique peut générer une estimation plus précise et probablement générer un plan qui utilisera l'indice.

Voici un exemple d'une mauvaise estimation de 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 |
-------------------------------------------------------------------------

Voici comment y remédier :

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)