加入收藏 | 设为首页 | 会员中心 | 我要投稿 吕梁站长网 (https://www.0358zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长百科 > 正文

Oracle - SPM固定执行计划(一)

发布时间:2020-12-30 12:04:57 所属栏目:站长百科 来源:网络整理
导读:一、前言 生产中偶尔会碰到一些sql,有多种执行计划,其中部分情况是统计信息过旧造成的,重新收集下统计信息就行了。但是有些时候重新收集统计信息也解决不了问题,而开发又在嗷嗷叫,没时间让你去慢慢分析原因的时候,这时临时的解决办法是通过spm去固定一

再新开一个窗口D,执行
SQL> set autot trace
SQL> select /*for_test*/ * from test1 where object_id = 1;

Execution Plan
----------------------------------------------------------
Plan hash value: 4122059633

---------------------------------------------------------------------------
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |       |   173K|    15M|   693   (1)| 00:00:09 |
|*  1 |  TABLE ACCESS FULL| TEST1 |   173K|    15M|   693   (1)| 00:00:09 |
---------------------------------------------------------------------------


可以看到执行计划为全表扫描,跟窗口A一样,这个是正常的

通过执行以下function去将执行计划固定为索引扫描
SQL> var temp number;
SQL> begin
:temp := dbms_spm.load_plans_from_cursor_cache(sql_id=>‘66a4184u0t6hn‘,plan_hash_value=>2214001748);
end;
/

再执行以下sql
SQL> select /*for_test*/ * from test1 where object_id = 1;

Execution Plan
----------------------------------------------------------
Plan hash value: 2214001748

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |    11 |  1056 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST1     |    11 |  1056 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_TEST1 |   173K|       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

Note
-----
   - SQL plan baseline "SQL_PLAN_9657urkb9u2tnf24a05ff" used for this statement


可以看到spm已经生效了


四、删除spm

当我们找到sql执行计划突变的原因了,解决问题之后,就可以删除spm了。如何删除spm呢?

新开窗口E
查看当前sql的执行计划基线
SQL> select sql_handle,plan_name,origin from dba_sql_plan_baselines where sql_text like ‘select /*for_test*/ * from test1%‘;

SQL_HANDLE                     PLAN_NAME                      ORIGIN
------------------------------ ------------------------------ --------------
SQL_9314fabc969d0b34           SQL_PLAN_9657urkb9u2tnf24a05ff MANUAL-LOAD
SQL_9314fabc969d0b34           SQL_PLAN_9657urkb9u2tnfe026eff AUTO-CAPTURE

?

可以看到该sql有两条PLAN_NAME,一个是系统自动捕获的,一个是我们手工绑定的,反正我们不再需要这个了,统统删除
通过执行以下function去将执行计划基线删除
SQL> var temp number;
SQL> begin
:temp := dbms_spm.drop_sql_plan_baseline(sql_handle=>‘SQL_9314fabc969d0b34‘,plan_name=>NULL);
end;
/

查看当前sql的执行计划基线
SQL> select sql_handle,origin from dba_sql_plan_baselines where sql_text like ‘select /*for_test*/ * from test1%‘;
no rows selected

再在窗口D中执行以下sql
SQL> select /*for_test*/ * from test1 where object_id = 1;

Execution Plan
----------------------------------------------------------
Plan hash value: 4122059633

---------------------------------------------------------------------------
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |       |   173K|    15M|   693   (1)| 00:00:09 |
|*  1 |  TABLE ACCESS FULL| TEST1 |   173K|    15M|   693   (1)| 00:00:09 |
---------------------------------------------------------------------------


可以看到执行计划又变成默认的全表扫描了

?

五、说明

文章例子整理于《基于oracle的sql优化》,后面将写另一个场景,就是如果系统里就一个执行计划,但是该执行计划是有问题的,如何去手工生成一个正确的执行计划,然后绑定。

(编辑:吕梁站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读