Будет ли оптимизатор Oracle использовать несколько подсказок в одном SELECT? - PullRequest
19 голосов
/ 07 января 2009

Я пытаюсь оптимизировать производительность запросов, и мне пришлось прибегнуть к использованию подсказок оптимизатора. Но я так и не узнал, будет ли оптимизатор использовать более одной подсказки за раз.

, например

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;

План объяснения показывает ту же стоимость, но я знаю, что это только оценка.

Предположим, что вся статистика таблиц и индексов рассчитана. К вашему сведению, индекс dcf_vol_prospect_ids_idx находится в столбце i.solicitor_id.

Спасибо

Стью

Ответы [ 3 ]

22 голосов
/ 07 января 2009

Попробуйте указать все подсказки в одном блоке комментариев, как показано в этом примере из замечательной документации 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 голосов
/ 08 января 2009

Фактически, рекомендация Джонатана Льюиса, автора основанных на затратах основ Oracle, заключается в том, что если CBO не удается найти правильный план, вам нужно взять на себя работу CBO и «наложить» подсказки в среднем две подсказки на таблицу в запросе.

Причина в том, что один намек может привести к еще одному плохому и, возможно, даже худшему плану, чем CBO получит без посторонней помощи. Если CBO не прав, вам нужно дать ему весь план, а не только толчок в правильном направлении.

1 голос
/ 22 января 2019

Представлен 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'));
                                                     --============

Показывает другой раздел Hint Report:

Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: ...
---------------------------------------------------
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...