Oracle还是比较常用的,于是我研究了一下Oracle INDEX提示,当使用hints时,在某些情况下,为了确保让优化器产生***的执行计划,我们可能指定全套的hints,在这里拿出来和大家分享一下,希望对大家有用。
例如,如果有一个复杂的查询,包含多个表连接,如果你只为某个表指定了Oracle INDEX提示(指示存取路径在该表上使用索引),优化器需要来决定其它应该使用的访问路径和相应的连接方法。因此,即使你给出了一个Oracle INDEX提示,优化器可能觉得没有必要使用该提示。这是由于我们让优化器选择了其它连接方法和存取路径,而基于这些连接方法和存取路径,优化器认为用户给出的Oracle INDEX提示无用。为了防止这种情况,我们要使用全套的hints,如:不但指定要使用的索引,而且也指定连接的方法与连接的顺序等。
下面是一个使用全套hints的例子,ORDERED提示指出了连接的顺序,而且为不同的表指定了连接方法:
- SELECT /*+ ORDERED INDEX (b, jl_br_balances_n1) USE_NL (j b)
- USE_NL (glcc glf) USE_MERGE (gp gsb) */
- b.application_id, b.set_of_books_id ,
- b.personnel_id, p.vendor_id Personnel,
- p.segment1 PersonnelNumber, p.vendor_name Name
- FROM jl_br_journals j, jl_br_balances b,
- gl_code_combinations glcc, fnd_flex_values_vl glf,
- gl_periods gp, gl_sets_of_books gsb, po_vendors p
- WHERE ...
指示优化器的方法与目标的hints:
- ALL_ROWS -- 基于代价的优化器,以吞吐量为目标
- FIRST_ROWS(n) -- 基于代价的优化器,以响应时间为目标
- CHOOSE -- 根据是否有统计信息,选择不同的优化器
- RULE -- 使用基于规则的优化器
例子:
- SELECT /*+ FIRST_ROWS(10) */ employee_id, last_name, salary, job_id
- FROM employees
- WHERE department_id = 20;
- SELECT /*+ CHOOSE */ employee_id, last_name, salary, job_id
- FROM employees
- WHERE employee_id = 7566;
- SELECT /*+ RULE */ employee_id, last_name, salary, job_id
- FROM employees
- WHERE employee_id = 7566;
【编辑推荐】