详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

概述

在实际的工作当中,可能会碰到在开发环境或测试环境中系统运行正常,但是移植到真实生产环境中却发现响应速度很慢,如果在调试之后效果仍然不佳的情况下,可以尝试使用outlines来稳定个别SQL语句的执行计划。


概念

Oracle Outline,中文也称为存储大纲,是最早的基于提示来控制SQL执行计划的机制,也是9i以及之前版本唯一可以用来稳定和控制SQL执行计划的工具。

outline是一个hints(提示)的集合,更具体的讲,outline可以锁定一个给定SQL的执行计划,保持其执行计划稳定,不管数据库环境如何变更(如统计信息,部分参数等)

注意:

从10g以后,oracle连续发布了sql profile和sql baseline来实现SQL执行计划的控制,并且outline这个工具基本已经被Oracle废弃并且不在维护,但是不管怎么说,在10g以及11g版本都还是可以使用,而且这个特性也一直使用的很好。

10g以后建议使用sql profile或者sql baseline

由于目前outline现在已经很少使用,此文也就主要介绍一些命令。

Outlines存储在表OL$,OL$HINTS和OL$NODES,可通过视图[USER|ALL|DBA]_OUTLINES 和 [USER|ALL|DBA]_OUTLINE_HINTS查询已存在的outlines的信息。


运行机制

Outline将执行计划的hint集合保存在outline的表中(数据字典)。当执行SQL解析时,Oracle会与outline中的SQL比较,如果该SQL有保存的outline,则通过保存的hint集合生成指定执行计划。

注意:

SQL解析时,使用SQL文本却匹配数据字典outline保存的文本,此处匹配的方式为去掉SQL空格,忽略SQL大小写区别后,进行的比较。

例如,select * from dual 和SELECT * FROM dual这两个语句将使用同样的outline。


创建outlines

Outlines创建可分为oracle自动和手动,通过参数create_stored_outlines来控制,create_stored_outlines的值可以是true/flase/category_name,可在实例级和会话级别修改。

1、开启自动创建 outlines.

ALTER SYSTEM SET create_stored_outlines=TRUE;
ALTER SESSION SET create_stored_outlines=TRUE;

2、关闭自动创建 outlines.

ALTER SYSTEM SET create_stored_outlines=FALSE;
ALTER SESSION SET create_stored_outlines=FALSE;

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

3、授权

CONN sys/password AS SYSDBA
GRANT CREATE ANY OUTLINE TO SCOTT;
GRANT EXECUTE_CATALOG_ROLE TO SCOTT;

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

4、创建outlines

把条件写成变量,主要是因为在实际的运用过程中会绑定变量。

create table t_outline as select * from dba_objects;
CREATE OUTLINE xx_id FOR CATEGORY xx_outlines ON select * from xx where id=:a;

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

5、检查outlines是否创建成功

SQL> select name,category,sql_text from user_outlines where category='T_OUTLINES';

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

6、列出和outlines有关的hints

SQL> select * from user_outline_hints where name='xx_ID';

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制


使用outlines

现在我们已经创建好了outlines,但是从下面查询可以看出outlines并没有被使用。

1、检查outlines是否使用

select name,category,used from user_outlines where category='T_OUTLINES';

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

2、执行下面的SQL语句

SQL> VAR a number;
SQL> DEFINE a = 32791;
SQL> select * from t_outline where object_id=:a;
no rows selected

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

3、再一次检查

SQL> select name,category,used from user_outlines where category='T_OUTLINES';

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

我们执行一遍SQL之后,outlines还是没使用,这是因为还没有启用。我们可以通过ALTER SYSTEM和ALTER SESSION命令去开启。下面将演示一下在会话级别启用outlines.

4、开启outlines

alter session set use_stored_outlines=t_outlines;

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

5、执行下面的SQL语句

SQL> VAR a number;
SQL> DEFINE a = 20;
SQL> select * from t_outline where object_id=:a;

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

6、检查

SQL> select name,category,used from user_outlines where category='T_OUTLINES';

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制


删除和清除outlines

删除outlines

SQL>execute DBMS_OUTLN.drop_by_cat('T_OUTLINES');

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

清除制定outlines

SQL> execute DBMS_OUTLN.CLEAR_USED(' T_OUTLINES ');

删除所有状态为unused(dba(all,user)_outlines中可查)的outline

SQL> execute DBMS_OUTLN.drop_unused;

上面讲的主要是10g以前的,从Oracle 11g开始,提供了一种新的固定执行计划的方法,即SQL plan baseline,中文名SQL执行计划基线(简称基线),可以认为是OUTLINE(大纲)或者SQL PROFILE的改进版本,后面会总结下执行计划基线方面的内容,感兴趣的朋友可以关注一下~

详解Oracle数据库OutLines的使用--控制SQL执行计划的机制

相关推荐