L'ottimizzatore prende la decisione in base al costo relativo della scansione completa della tabella e all'utilizzo dell'indice. Ciò dipende principalmente dal numero di blocchi da leggere per soddisfare la query. La regola del 25%/75% menzionata in un'altra risposta è semplicistica: in alcuni casi una scansione completa della tabella avrà senso anche per ottenere l'1% delle righe, ad esempio se queste righe vengono distribuite su molti blocchi.
Ad esempio, considerare questa tabella:
SQL> create table t1 as select object_id, object_name from all_objects;
Table created.
SQL> alter table t1 modify object_id null;
Table altered.
SQL> update t1 set object_id = null
2 where mod(object_id,100) != 0
3/
84558 rows updated.
SQL> analyze table t1 compute statistics;
Table analyzed.
SQL> select count(*) from t1 where object_id is not null;
COUNT(*)
----------
861
Come si può vedere, solo approssimativamente 1% delle righe T1 hanno un object_id non nullo.Ma a causa del modo in cui ho costruito la tabella, queste 861 righe saranno distribuite più o meno uniformemente attorno al tavolo. Pertanto, la query:
select * from t1 where object_id is not null;
è probabilità di visitare quasi ogni blocco in T1 per ottenere i dati, anche se l'ottimizzatore utilizzato l'indice. Ha senso quindi fare a meno dell'indice e fare una scansione completa della tabella!
Una statistica chiave per aiutare a identificare questa situazione è il fattore indice di clustering:
SQL> select clustering_factor from user_indexes where index_name='T1_IDX';
CLUSTERING_FACTOR
-----------------
460
Questo valore 460 è abbastanza alto (rispetto ai 861 righe dell'indice), e suggerisce che una scansione completa della tabella sarà essere usato. Vedi this DBAZine article on clustering factors.
fonte
2009-04-06 16:46:53
Quassnoi, dove stai ottenendo quel 75%? Se ci sono un milione di righe e solo una è nullo, perché usare un indice su quelle colonne è più lento di una scansione della tabella? – tpdi
Poiché l'indice impedisce l'unione nascosta su ROWID, che costa circa 4 volte tanto quanto la scansione della tabella. La selettività dell'indice è inferiore al 25%, la scansione della tabella è solitamente più veloce. – Quassnoi
In una scansione completa della tabella, si esegue semplicemente un'iterazione su tutte le righe della tabella; se fai una scansione dell'indice, devi prima leggere l'indice e poi leggere la tabella. Da un certo punto il costo della lettura di un indice è più alto della semplice lettura dell'intera tabella. – andri