Ответ
Полное сканирование таблицы (FULL TABLE SCAN) часто эффективнее индексного доступа в следующих случаях:
- Низкая селективность запроса: Когда условие
WHEREотбирает большую часть строк таблицы (обычно более 20-30%). В этом случае оптимизатору выгоднее прочитать все блоки таблицы последовательно, чем выполнять множество случайных чтений через индекс с последующими обращениями к таблице за остальными полями. - Необходимость чтения большинства столбцов: Если запрос
SELECT *или выбирает много столбцов, не входящих в покрывающий индекс (covering index), то после индексного сканирования все равно потребуется дорогостоящий доступ к самой таблице (TABLE ACCESS BY INDEX ROWID). - Маленький размер таблицы: Если таблица занимает всего несколько блоков базы данных, то ее полное сканирование выполняется очень быстро.
- Отсутствие подходящего индекса или необходимость принудительного сбора статистики: Иногда полное сканирование используется для быстрого обновления статистики по таблице командой
DBMS_STATS.
Пример:
-- Скорее всего, вызовет FULL SCAN, если статус 'ACTIVE' имеют >40% записей.
SELECT user_id, name, email FROM users WHERE status = 'ACTIVE';
-- Индекс по user_id будет эффективен, так как выбирается одна запись.
SELECT * FROM orders WHERE user_id = 12345;
Важно: Современные оптимизаторы (Oracle, PostgreSQL) на основе статистики сами выбирают оптимальный план. Понимание этой логики помогает в проектировании индексов и написании эффективных запросов.