2008年(239)
分类:
2008-06-17 23:40:46
优化器根据数据字典信息,通过估算找出SQL语句费用最低的执行计划。这种估算方式,并不能保证优化器找出的执行计划都是最优的。在下列情况下,优化器选择的执行计划可能会很糟糕:
(1)SQL语句非常复杂
(2)SQL语句的书写存在问题
(3)数据字典中没有足够的统计信息
为了避免这种情况的发生,我们希望通过一些设置,影响优化器的动作,进而限制执行计划的选择。毕竟用户对数据库中表、索引的结构非常了解,大体上知道SQL语句应当怎样被执行。这可以通过在SQL语句中加入指示信息(directive)来实现。
加入SQL语句的指示信息并不是SQL语句的一部分,它们相当于一些注释,告诉优化器应当采用什么样的动作、作出什么样的选择。具体来说,一些常用的、比较关键的指示信息有以下这些:
(1)是否使用表扫描
(2)是否使用索引以及使用那一个索引
(3)设定表的连接顺序以及连接方式
例如,可以使用下列SQL语句,从员工表employee中返回所有员工的姓名:
SELECT empy_name
FROM employee
如果用户希望优化器通过员工表索引empy_ind进行数据访问,可以在SQL语句中加入index指示。
SELECT --+index(empy_ind) empy_name
FROM employee
又如,可以使用下列SQL语句,返回月工资超过5000的所有员工姓名及所在部门:
SELECT a.empy_name,b.dept_name
FROM employee a, department b
WHERE a.dept_no = b.dept_no AND a.salary > 5000
用户可以在SQL语句中加入avoid_full指示,希望优化器不要使用表扫描访问员工表employee;加入ordered指示,让优化器根据员工表employee、部门表department在SQL语句中的顺序执行表的连接:
SELECT --+ordered, avoid_full(a) a.empy_name,b.dept_name
FROM employee a, department b
WHERE a.dept_no = b.dept_no AND a.salary > 5000
SQL语句中的指示信息,在影响优化器处理过程的同时,降低了优化处理所需要的工作量,是一种值得尝试的有用工具。然而对用户来说,在SQL语句中使用指示信息,除了增加工作量、要求对表和索引的结构以及表中的数据存放有深入的了解之外,还要求深入掌握系统对SQL语句的处理和执行方式,使用起来有相当大的难度。
需要说明的是,指示信息并不总是能带来好的结果,错误的指示信息只会使优化器做出错误的选择,进而影响SQL语句的执行。另外,在对表进行大量的数据处理、表中的数据存放已经发生了较大的变化之后,可能需要更改指示信息,以调整SQL语句的执行方式。
一般来说,用户应当了解SQL语句的指示信息,但不建议直接在SQL语句中使用。用户可以通过简化和优化SQL语句、定期地维护以及收集统计信息等更方便、更有效的方式,避免优化器作出不正确的选择。