首页 > Linux操作系统 > Linux操作系统 > 关于执行计划稳定性(一)
从oracle8i开始,提供了稳定执行计划的功能。也就是预先将调试好的sql的执行计划保存下来,以后即使sql执行的环境发生了某些变化,比如插入大量数据后重新分析了表,重新生成了数据分布柱状图等,还是可以使用预先保存的执行计划,不受这些因素的影响。
执行计划稳定性是通过创建outline来实现的,具体的执行计划就保存在不同的outline中,outline则属于不同的category。一个session只能有一个category生效。
关于执行计划稳定性(二):http://ningoo.itpub.net/post/2149/247477
关于执行计划稳定性(三):http://ningoo.itpub.net/post/2149/247479
一个简单的例子,演示如何稳定执行计划
1.试验环境
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> show parameter statistics_level
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
statistics_level string TYPICAL
2.创建测试表
SQL> create table t as select * from all_objects;
表已创建。
3.执行查询,发现是全表扫描
SQL> select count(*) from t;
执行计划
----------------------------------------------------------
Plan hash value: 2966233522
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 31 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| T | 9787 | 31 (0)| 00:00:01 |
-------------------------------------------------------------------
4.创建index后,执行计划变成了index range scan
SQL> create index ix_t on t(object_id);
索引已创建。
注意object_id是有not null约束的,所以count(*)可以使用该index。
SQL> select count(*) from t;
执行计划
----------------------------------------------------------
Plan hash value: 281895819
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 6 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IX_T | 9787 | 6 (0)| 00:00:01 |
----------------------------------------------------------------------
5.删除index,创建outline保存全表扫描的执行计划
SQL> drop index ix_t;
索引已删除。
SQL> create or replace outline myoutline
2 for category mycategory
3 on
4 select count(*) from t;
大纲已创建。
6.再次创建index
SQL> create index ix_t on t(object_id);
索引已创建。
SQL> select count(*) from t;
执行计划
----------------------------------------------------------
Plan hash value: 2966233522
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IX_T | 8953 | 7 (0)| 00:00:01 |
-------------------------------------------------------------------
7.在当前session应用mycategory,则执行计划又变回了全表扫描
SQL> alter session set use_stored_outlines=mycategory;
会话已更改。
SQL> select count(*) from t;
执行计划
----------------------------------------------------------
Plan hash value: 2966233522
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 31 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| T | 9787 | 31 (0)| 00:00:01 |
-------------------------------------------------------------------
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/193161/viewspace-50266/,如需转载,请注明出处,否则将追究法律责任。