20

我正在尝试优化查询性能,不得不求助于使用优化器提示。但是我从来没有知道优化器是否一次会使用多个提示。

例如

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 列上。

谢谢,

4

3 回答 3

24

尝试在单个注释块中指定所有提示,如精彩的 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;
于 2009-01-07T20:49:58.043 回答
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'));
                                                     --============

它显示了另一部分Hint Report

Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: ...
---------------------------------------------------
...
于 2019-01-22T15:46:04.180 回答
2

事实上,基于成本的 Oracle Fundamentals 的作者 Jonathan Lewis 的建议是,如果 CBO 未能找到正确的计划,您需要接管 CBO 的工作并“嵌入”提示 - 平均查询中每个表有两个提示。

原因是,一个提示可能会导致另一个糟糕的甚至可能比 CBO 没有帮助的计划更糟糕。如果 CBO 错了,你需要给它整个计划,而不仅仅是朝着正确的方向轻推。

于 2009-01-07T22:47:24.673 回答