Оптимизатор примет решение на основе относительной стоимости полного сканирования таблицы и использования индекса. Это в основном сводится к тому, сколько блоков нужно будет прочитать, чтобы удовлетворить запрос. Практическое правило 25% / 75%, упомянутое в другом ответе, является упрощенным: в некоторых случаях полное сканирование таблицы будет иметь смысл даже для получения 1% строк, т. Е. Если эти строки распределены вокруг множества блоков.
Например, рассмотрим следующую таблицу:
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
Как видите, только приблизительно 1% строк в T1 имеют ненулевой object_id. Но из-за того, как я построил таблицу, эти 861 строка будут более или менее равномерно распределены вокруг таблицы. Поэтому запрос:
select * from t1 where object_id is not null;
, вероятно, посетит почти каждый блок в T1, чтобы получить данные, даже если оптимизатор использовал индекс. Тогда имеет смысл обойтись без индекса и перейти к полному сканированию таблицы!
Ключевой статистикой, помогающей идентифицировать эту ситуацию, является коэффициент кластеризации индекса:
SQL> select clustering_factor from user_indexes where index_name='T1_IDX';
CLUSTERING_FACTOR
-----------------
460
Это значение 460 довольно высокое (по сравнению с 861 строкой в индексе) и предполагает, что будет использовано полное сканирование таблицы. См. эту статью DBAZine о факторах кластеризации .