Я думаю, что вижу, что здесь происходит.
Когда у вас есть индекс, и вы делаете:
SELECT Occupation FROM EMPLOYEE WHERE Occupation = 'DOCTOR';
План выполнения будет использовать индекс.Это не сложно, потому что все данные, необходимые для удовлетворения запроса, прямо в индексе, и Oracle даже не нужно ссылаться на таблицу вообще.
Однако, когда вы делаете:
SELECT Fname FROM EMPLOYEE WHERE Occupation = 'DOCTOR';
затем, если Oracle использует индекс, он выполнит сканирование индекса INDEX RANGE, а затем TABLE ACCESS BY ROWID, чтобы найти имя F, соответствующее этому занятию.Теперь, в зависимости от того, сколько строк имеет DOCTOR для Occupation, Oracle придется совершить одну или несколько поездок в таблицу, чтобы найти Fname.Если, например, у вас есть таблица, и для всех сотрудников установлено значение «Занятие» - «DOCTOR», индекс будет бесполезен, и Oracle просто выполнит полный просмотр таблицы.Если в компании 10 000 сотрудников, и только один из них является ДОКТОРОМ, то, опять же, это не сложно, и Oracle будет использовать этот индекс.
Но есть некоторые тонкости, когда вы находитесь где-то между этими двумя крайностями,Людям нравится говорить о «избирательности», т. Е. О том, сколько строк идентифицируется индексом, в зависимости от размера таблицы, когда обсуждают, будет ли индекс использоваться.Но это не действительно правда.Oracle действительно заботится о селективности блоков .То есть, сколько блоков нужно посетить, чтобы удовлетворить запрос?Итак, во-первых, насколько «широкий» диапазон сканирования?Чем более ограничен диапазон значений, указанных значениями предиката, тем лучше.Во-вторых, когда ваш запрос должен выполнить поиск в таблице, сколько разных блоков ему нужно будет посетить, чтобы найти все необходимые ему данные.То есть насколько «случайными» являются данные в таблице относительно порядка индекса?Это называется CLUSTERING_FACTOR.Если вы проанализируете индекс для сбора статистики, а затем посмотрите на USER_INDEXES, вы увидите, что CLUSTERING_FACTOR теперь заполнен.
Итак, что такое CLUSTERING_FACTOR?CLUSTERING_FACTOR - это упорядоченность таблицы по отношению к ключевым столбцам индекса.Значение CLUSTERING_FACTOR всегда будет между числом блоков в таблице и количеством строк в таблице.A low CLUSTERING_FACTOR, то есть тот, который очень близок к числу блоков в таблице, указывает на очень упорядоченную таблицу относительно индекса. high CLUSTERING_FACTOR, то есть тот, который очень близок к числу строк в таблице, очень неупорядочен по отношению к индексу.
ЭтоВажно понимать, что CLUSTERING_FACTOR описывает порядок данных в таблице относительно индекса.Так, например, перестройка индекса не изменит CLUSTERING_FACTOR.Также важно понимать, что одна и та же таблица может иметь два индекса, и у одного может быть отличный CLUSTERING_FACTOR, а у другого может быть очень плохой CLUSTERING_FACTOR.Сам стол можно заказать только одним способом.
Итак, почему я потратил так много времени на описание CLUSTERING_FACTOR? Потому что, если у вас есть план выполнения, выполняющий сканирование индекса INDEX RANGE, за которым следует TABLE ACCESS BY ROWID, вы можете быть уверены, что CLUSTERING_FACTOR был рассмотрен оптимизатором Oracle для составления плана выполнения. Например, предположим, что у вас есть таблица из 10000 строк, и предположим, что 100 строк имеют Occupation = 'DOCTOR' Вы пишете запрос выше, спрашивая имя и фамилию сотрудников, чья профессия - ДОКТОР. Что ж, Oracle может очень легко и эффективно определить значения строк строк, в которых занятие - DOCTOR. Но сколько блоков table нужно посетить Oracle, чтобы выполнить поиск по Fname? Это может быть только 1 или 2 табличных блока, если данные кластеризованы (упорядочены) по профессии в таблице. Но это может быть целых 100, если данные очень неупорядочены в таблице! Итак, снова 10000 строк таблицы и, допустим, (в целях иллюстрации и простой математики), что таблица имеет 100 строк / блок и, таким образом, 100 блоков. В зависимости от порядка таблиц (например, CLUSTERING_FACTOR) число посещений блоков таблицы может составлять всего 1 или 100.
Итак, я надеюсь, что это поможет вам понять, почему оптимизатор может неохотно использовать индекс в некоторых случаях.