#oracle #indexing
#Oracle #индексирование
Вопрос:
У меня есть таблица
Name | Postal_CODE
Я создал индекс в Postal_Code как
CREATE INDEX MNO on Table1(Postal_code).
но, когда я вижу план выполнения
select * from Table1 where Postal_code is not null
он показывает полное сканирование Table1.Он не использует индекс.
Есть идеи, почему?
Комментарии:
1. Сколько строк в вашей таблице?
2. Можете ли вы также опубликовать план объяснения?
3. Сколько из 13 миллионов являются нулевыми?
4. Кроме того, показывает ли план объяснения полное сканирование таблицы или быстрое полное сканирование индекса?
5. ОН ПОКАЗЫВАЕТ «ДОСТУП К ПОЛНОЙ ТАБЛИЦЕ ТАБЛИЦЫ»
Ответ №1:
Индексы BTree Oracle не хранят нулевые значения. Это означает, что вам нужно получить все строки из индекса, и в этом случае будет быстрее использовать полное сканирование.
Ответ №2:
Если более 10% (приблизительно) строк в таблице имеют postal_codes, то Oracle более эффективно выполнять быстрое полное сканирование или полное сканирование таблицы, чем использовать индекс.
(10% — это очень грубое эмпирическое правило. YMMV.)
Комментарии:
1. Я бы подумал, что он выполнит быстрое полное сканирование индекса, если бы это было так?
2. Я только что протестировал таблицу с 16,3 миллионами строк, подавляющее большинство из которых не являются нулевыми, и только несколько нулей, количество ненулевых значений использовало быстрое полное сканирование индекса. Oracle 10g (10.2.0.4)
3. Вы совершенно правы, я виноват. Я в основном сосредоточился на том, что «не будет использовать индексную часть», а не на правильном определении типа сканирования. Ответ изменен.
Ответ №3:
В этой ситуации Oracle не будет сохранять ссылку на строки, где Postal_code имеет значение null. Поэтому он не будет использовать индекс. Это тоже не так просто, поскольку Oracle, возможно, определила, что стоимость использования индекса дороже, чем выполнение сканирования таблиц.