2014-01-29 3 views
3

У нас есть таблица «Клиенты» с колонками электронной почты и сайта. И есть индекс, состоящий из этих двух столбцов. Таким образом, связанные запросы всегда используют этот индекс при выполнении запросов и фильтрации по электронной почте, как это:Почему индекс не используется для некоторых значений?

select * from customers where email = '[email protected]'; 

Уверяем индекс был использован, потому что мы проверили запрос с объяснить план. Теперь у нас был интересный случай вчера. Тот же запрос с предложением «email =« [email protected] »вообще не использовал индекс. Объяснение плана показало, что оракул выполнил полное сканирование. Таблица содержит миллионы записей, поэтому этот запрос без индекса ударил 30 секунд. в запросе использовался индекс с любыми другими значениями электронной почты ([email protected], [email protected]). Каковы причины, по которым оракул не использовал индекс?

Одна из причин, по которым мне приходит индекс не содержит такого значения, поэтому сначала оракул пересекает индекс, а затем выполняет полное сканирование, но затем объясняет, что план должен показать, что он выполнил сканирование индекса. В нашем случае план объяснения показывает полное сканирование. Другая причина связана с восстановлением db, но также не уверен, каким может быть индекс, который не содержит такого значения.

UPDATE Все таблицы после восстановления, имеют значение last_analyzed даты недели недели. В этом конкретном случае с электронной почтой все электронные письма обновляются до некоторых случайных значений из-за конфиденциальности клиентов после обновления. Таблица клиентов имеет несколько миллионов записей, поэтому да, после восстановления произошли весьма значительные изменения, но до сих пор не понят, как это может быть связано с тем, чтобы не использовать электронную почту, потому что эта таблица клиентов уже имеет миллионы записей перед восстановлением.

UPDATE2 Этот индекс используется после того, как мы выполнили сбор статистики по таблице.

UDATE3 ну, все значения электронной почты уникальны в таблице клиентов, поэтому маловероятно, что CBO решило, что слишком много строк с таким электронным письмом. Просто есть много писем с одинаковыми стартовыми символами «random ...», но это не следует рассматривать как идентичные значения, верно?

+0

ли таблица содержит частые вставки и удаления? – arunb2w

+2

Он не выполнил бы полного сканирования, если бы не нашел индексный удар; он будет делать то или другое, а не то, и другое. (Проделали ли это полное сканирование индекса или полное сканирование таблицы?) Предполагая, что ваша статистика актуальна, имеет ли индекс гистограммы, и есть ли у вас много адресов, похожих на те, которые ведут себя по-другому? –

+0

Я согласен с Алексом, это может быть причиной того, что, поскольку мощность для конкретного идентификатора электронной почты высока, Oracle собирается полностью сканировать таблицу. – San

ответ

2

Сервер не будет смотреть на данные в индексе, а затем сканировать таблицу, если не найден. Прежде чем он что-либо сделает, он посмотрит статистику, чтобы увидеть, следует ли использовать индекс или сканировать таблицу. Я бы предположил, что адрес электронной почты, по какой-то причине, сделал oracle, подумайте, что лучше сканировать таблицу, чем смотреть на индекс. Слишком много факторов, чтобы прийти к точному выводу. Ознакомьтесь с этой информацией по статистике Oracle Doc on Stats. Вы можете взглянуть на изменение количества данных, которое имеет статистика для обложек индексов, и это поможет.

+2

Из описания, которое я начал бы с [смотря на гистограммы] (http://docs.oracle.com/cd/B13789_01/server.101/b10752/stats.htm # 40819) в качестве основания для этого решения. –

+0

@AlexPoole Интересный материал, спасибо. Также см. Обновленный вопрос. – Centurion

0

Гистограммы учитывают только 32 байт. Насколько велики одинаковые стартовые символы? См. this Oracle Optimizer post.

Перемещение уникальных символов в начале строки или отключите гистограмм с чем-то вроде этого:

begin 
    dbms_stats.set_table_prefs 
    (
    '<schema>', 
    'CUSTOMERS', 
    'METHOD_OPT', 
    'FOR ALL COLUMNS SIZE AUTO, FOR COLUMNS SIZE 1 EMAIL' 
); 
end; 
/
+0

Интересный момент, но в нашем случае электронные письма, начинающиеся с «random ..», содержат только 6 одинаковых байтов (случайных), поэтому гистограммы также должны учитывать и другие символы. – Centurion

Смежные вопросы