Хмммм, у меня атака дежавю .
В любом случае, вот над чем нужно работать:
3433602 consistent gets
Три миллиона логических операций ввода-вывода потратят много времени, поэтому вам нужно уменьшить это число.
Ваш запрос состоит из трех наборов обращений к одной и той же таблице. Каждый доступ состоит из чтения индекса, за которым следует чтение таблицы. Из вашего комментария к вопросу Питера кажется, что ваша статистика достаточно точна (запрос возвращает 699415 строк, NUM_ROWS
= 697608).
Настройка - сложное занятие с множеством факторов, которые необходимо учитывать. Мы могли бы легко потратить полдня на то, чтобы разобраться во всем, что может быть не так в этом одном запросе.
Например, собираете ли вы статистику для своих индексов, а также для таблицы (в более ранних версиях Oracle по умолчанию не собиралась статистика индекса)? Если у вас есть статистика, каков фактор кластеризации этих индексов? Все ваши обращения к индексу являются сканированием, поэтому фактор кластеризации имеет значение.
Нам нужен низкий коэффициент кластеризации, потому что это означает, что индекс должен выполнять меньше работы, чтобы получить строки из таблицы. Если коэффициент кластеризации ближе к количеству записей в индексе, это плохо, тогда как, если он ближе к количеству блоков в таблице, это хорошо. Увы, учитывая количество ЛИО, которые вы испытываете, мои деньги направлены на плохие факторы кластеризации. Таким образом, вы должны получить больше сока из индексов.
Глядя на ваш запрос, столбцы в самой внешней проекции используются в предложении WHERE запроса и / или подзапросах. Несмотря на этот факт, вы используете три разных индекса, и ни один из них не предоставляет всю информацию, необходимую для соответствия критериям (отсюда дополнительная таблица читает и последующая фильтрация). Одна из тактик, которая может быть очень эффективной в таких ситуациях, - это создать супериндекс, содержащий все необходимые столбцы.
create index N_USER_ROLE_IDX23 on user_role
( active
, role_id
, user_id
, participant_code
, effective_from_date
, effective_to_date
, last_update_date )
Это приводит к ACTIVE и ROLE_ID, потому что эти столбцы используются во всех трех наборах критериев. (Кстати, ваш третий запрос говорит это:
WHERE S.role_id = r.role_id
AND S.role_id = r.role_id
Это правильно? ) В любом случае, смысл этого индекса в том, что он удовлетворяет всем трем предложениям WHERE и окончательному прогнозу, поэтому он вообще устраняет необходимость касаться таблицы. Следовательно, это может значительно сократить количество последовательных приобретений.