我正在尝试优化查询性能,不得不求助于使用优化器提示。但我从来没有学过优化器是否会一次使用多个提示。
e.g。
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列上。
谢谢,
炖
答案 0 :(得分:22)
尝试在单个注释块中指定所有提示,如本例中的精彩Oracle文档(http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm)所示。
16.2.1指定一整套提示
使用提示时,在某些情况下,您 可能需要指定一整套 提示以确保最佳 执行计划。例如,如果你 有一个非常复杂的查询,其中 由许多表连接组成,如果 您只为a指定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;
答案 1 :(得分:2)
事实上,基于成本的Oracle基础知识作者Jonathan Lewis的建议是,如果CBO未能找到正确的计划,您需要接管CBO的工作并“提入”提示 - 查询中每个表平均有两个提示。
原因在于,一条暗示可能会导致另一个糟糕甚至可能更糟糕的计划,而不是CBO可以独立完成的计划。如果CBO错了,你需要给它整个计划,而不仅仅是朝着正确的方向推进。
答案 2 :(得分:1)
Oracle 19c引入了here:
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: ...
---------------------------------------------------
...