Будет ли оптимизатор Oracle использовать несколько подсказок в одном и том же SELECT?
Я пытаюсь оптимизировать производительность запросов и прибегать к использованию подсказок оптимизатора. Но я никогда не узнал, будет ли оптимизатор использовать несколько подсказок за раз.
например.
SELECT /*+ INDEX(i dcf_vol_prospect_ids_idx)*/
/*+ LEADING(i vol) */
/*+ ALL_ROWS */
i.id_number,
...
FROM i_table i
JOIN vol_table vol on vol.id_number = i.id_number
JOIN to_a_bunch_of_other_tables...
WHERE i.solicitor_id = '123'
AND vol.solicitable_ind = 1;
План объяснения показывает ту же стоимость, но я знаю, что это просто оценка.
Предположим, что были рассчитаны все статистические данные таблиц и индексов. FYI, индекс dcf_vol_prospect_ids_idx находится в столбце i.solicitor_id.
Спасибо,
рагу
Ответы
Ответ 1
Попробуйте указать все подсказки в одном блоке комментариев, как показано в этом примере, из замечательной документации Oracle (http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm).
16.2.1 Определение полного набора подсказок
При использовании подсказок, в некоторых случаях, вы может потребоваться указать полный набор намеки, чтобы обеспечить оптимальное план выполнения. Например, если вы имеют очень сложный запрос, который состоит из множества табличных объединений, и если вы указываете только подсказку INDEX для данной таблице, то оптимизатор нуждается в для определения оставшегося доступа пути, которые будут использоваться, а также соответствующие методы объединения. Следовательно, хотя вы указали подсказку INDEX, оптимизатор может не обязательно используйте этот подсказку, потому что оптимизатор могли бы определить, что запрошенный индекс не может быть использован из-за методы соединения и пути доступа выбранный оптимизатором.
В примере 16-1 подсказка LEADING определяет точный порядок соединения, который должен быть используемый; методы соединения, которые будут использоваться на разные таблицы также указано.
Пример 16-1 Задание полного набора Советы
SELECT /*+ LEADING(e2 e1) USE_NL(e1) INDEX(e1 emp_emp_id_pk)
USE_MERGE(j) FULL(j) */
e1.first_name, e1.last_name, j.job_id, sum(e2.salary) total_sal
FROM employees e1, employees e2, job_history j
WHERE e1.employee_id = e2.manager_id
AND e1.employee_id = j.employee_id
AND e1.hire_date = j.start_date
GROUP BY e1.first_name, e1.last_name, j.job_id ORDER BY total_sal;
Ответ 2
В самом деле, рекомендация Джонатана Льюиса (Jonathan Lewis), автора основанных на затратах оснований Oracle заключается в том, что, если CBO не сможет найти правильный план, вам нужно взять на себя работу CBO и "наложить" подсказки - в среднем по двум подсказкам в таблице в запросе.
Причина в том, что один намек может привести к еще одному плохому и, возможно, даже худшему плану, чем CBO получит без посторонней помощи. Если CBO ошибочен, вам нужно дать ему весь план, а не просто подтолкнуть в правильном направлении.
Ответ 3
В Oracle 19c появилась функция отчетов по использованию подсказок:
EXPLAIN PLAN FOR
SELECT /*+ INDEX(i dcf_vol_prospect_ids_idx)*/
/*+ LEADING(i vol) */
/*+ ALL_ROWS */
i.id_number,
...
FROM i_table i
JOIN vol_table vol on vol.id_number = i.id_number
JOIN to_a_bunch_of_other_tables...
WHERE i.solicitor_id = '123'
AND vol.solicitable_ind = 1;
SELECT * FROM table(DBMS_XPLAN.DISPLAY(FORMAT=>'BASIC +HINT_REPORT'));
--============