Oracle的SQL性能优化 (六)终极优化:优化执行计划
Oracle可以通过hint指定调整SQL的执行计划,当Oracle没有把SQL优化好的情况下,检查执行计划,找到性能差的部分,就可以加hint来尝试新的执行计划,比较后找到最优的执行计划,从而实现SQL的调优。方法主要有改变所使用的索引和表关联方式。
索引hint的格式为 index(table_name index_name)
表的关联方式常用的有:
NestedLoop Join:在表关联时如果先读主表,再用外键逐个读取子表,性能相当良好,应该优先选择。其hint格式为 use_nl(table1 table2)。
Hash Join: 两个表分布读取符合查询条件的全部数据,然后根据关联字段建立哈希表找出匹配的数据。其hint格式为 use_hash(table1 table2)。
Merge Join:两个表分布读取符合查询条件的全部数据,分别根据关联字段排序,再建立连接后返回结果,一般来说,此关联方式是性能最差的。其hint格式为use_merge(table1 table2)。
可以看出,读取表数据的方式与表的关联方式实际上是有个一定关系的。可以相互影响,即加了index的hint可以改变表的关联方式,加了join的hint可以改变所使用的index。为了确保关联关系,有时会加ordered提示要求表按出现的先后顺序进行关联。
这几种Hint一般都是加到紧跟着select之后的注释块中,仅对当前的查询块有效,如果这个查询块是一个子查询,则这些hint不能应用到外面的查询中。
以下是优化过的SQL与执行计划
select /*+gather_plan_statistics ordered use_nl(emp dept)*/ dept.dept_name,emp.emp_name
from emp,dept
where dept.dept_id=emp.dept_id
and emp.emp_name like 'Emp9%'

由于表emp的emp_name上没有索引,因此必须对emp表进行全表扫描,根据条件emp.emp_name like 'Emp9%'取到emp数据,在根据emp的dept_id到dept表中找到合适的dept_name。所优化后的执行计划没有取到任何多余的数据,而且读取的次数也不多,因此应该是采用了最精确的方式找到了所需要的数据。