使用SPM固定执行计划
使用SPM固定执行计划
数据库在运行过程中,会由于各种原因的变化,存在执行计划不稳定的情况。Oracle 11g开始有SQL Plan Management来管理,稳定执行计划。
一般执行计划不稳定有以下几种原因引起(包括但不限于):
- 数据倾斜
- 统计信息不准确
- 数据库升级
1. 绑定变量带来的问题
从Oracle 9i开始,引进了绑定变量窥视(bind peeking)新特性,在对数据倾斜的绑定变量中,在ORACLE第一次解析SQL时会将变量的真实值代入产生执行计划,以后对所有的同样的绑定变量SQL都采用这个执行计划了。这种特性在大部分情况下能结合绑定变量减少SQL的解析时间,但对存在数据倾斜的SQL有可能产生极其糟糕的执行计划。
在11g开始,引进自适应游标共享(Adaptive Cursor Sharing,ACS),对一个绑定变量生成多个子执行计划,以求减低数据倾斜对执行计划的影响,从而达到动态调整执行计划的目的。
1.1 绑定变量相关视图
v$sql
中新增IS_BIND_SENSITIVE和IS_BIND_AWARE字段:
1
|
select is_bind_sensitive, is_bind_aware, sql_id, child_number
|
如果游标中存在绑定变量,数据库会根据传入的实际值判断不同的值能否会影响执行计划,如果会,则游标被标记为Bind-Sensitive
。在v$sql视图中的IS_BIND_SENSITIVE值则为Y。
当该SQL被执行过几次后,数据库会根据传入的实际值来决定是否需要修改执行计划,如果需要,则该游标是Bind-Aware
,在v$sql视图中IS_BIND_AWARE
也被标记为Y。
V$SQL_CS_SELECTIVITY
视图则展示了不同值的selectivity。V$SQL_CS_STATISTICS
视图展示了标记为Bind-Sensitive
和Bind-Aware
游标的一些统计信息,如内存读,CPU时间等。
1
|
select child_number,
|
1.2 查询绑定变量值
- 从AWR查找
1
|
col name for a30
|
- 从cursor中查找
1
|
select ADDRESS
|
1.3 从共享内存中删除游标
- 通过SQL ID查找SQL地址及hash值
1
|
--查找sql的address和hash_value
|
- 调用dbms_shared_pool清除游标
将产生的address及hash_value代入 &1, &2, 其中,c代表需要purge的类型是cursor,r表示trigger,q表示sequence等.
1
|
exec dbms_shared_pool.purge('&1,&2','C');
|
2. 如何使用SPM管理执行计划
2.1 相关术语
-
SPM
SPM是管理SQL执行计划的框架。其主要目的是防止由于执行计划改变而导致的SQL性能的退化。同时也提供了动态调整SQL执行计划的框架。 -
SQL Plan Baseline
当一个新的执行计划产生时候,SPM不一定会立即启用它,只有确认这些执行计划不会带来性能下降或者能提升性能,SPM才会采用(Accepted),而这些accepted的执行计划则被成为baseline(以下简称基线)。 -
Plan Evolution
把accepted的执行计划加入到基线的过程。 -
SQL Management Base(SMB)
存储基线、执行计划历史等的数据字典。
2.2 工作原理
SPM通过两个动态初始化参数进行控制, 两个参数均为PDB级别可修改。
- optimizer_capture_sql_plan_baselines
自动识别重复的SQL语句,并且为这些语句生成基线(从另一个侧面说明,SPM需要结合绑定变量使用,如果不使用绑定变量,建议使用SQL profile+ force_match参数)。该参数默认为false。 - optimizer_use_sql_plan_baselines
启用或者关闭SMB中的基线,默认为true。当启用时,优化器会从SMB中查找相应的基线并且挑选cost最小的作为该SQL的执行计划;如果是新执行计划,数据库会自动把这些新计划以unaccepted状态加入到基线中。
如果存在基线,优化器根据新产生的执行计划是否在基线中而作出不同选择:
- 如果新计划在基线中,则会执行此计划
- 如果新计划不在基线中,优化器会把新产生的执行计划标记为accepted,且加入到plan history中,接下来优化器会根据以下情况作出不同选择:
- 如果fixed plan存在于基线中,优化器会使用最低代价的fixed plan
- 如果没有fixed plan,优化器挑选基线中代价最低的
- 如果基线中不存在reproduced的执行计划,比如所有执行计划相关的索引都drop掉了,优化器会采用新产生的执行计划
2.3 创建基线
创建基线有以下几种方式:
- 使用SQL Tuning Set(STS)
- 从缓存/AWR中加载(new for 12.2)
- 从其他库导出并导入
- 自动收集(optimizer_capture_sql_plan_baselines=TRUE)
2.3.1 从缓存中进行加载
- 游标中已经存在较优的执行计划:
1
|
declare
|
- 通过filter筛选SQL
1
|
exec :pls := dbms_spm.load_plans_from_cursor_cache( -
|
2.3.2 从AWR中加载
1
|
exec pls := dbms_spm.load_plans_from_awr(begin_snap => &1, end_snap => &2);
|
2.4 查询基线
通过以下视图查询基线状态:
1
|
select sql_text, plan_name, enabled, accepted from dba_sql_plan_baselines;
|
dba_sql_plan_baselines
中栏位的含义:
如果是Enabled=No或者是Reproduced=No, 则优化器不会考虑相关的执行计划。
可通过dbms_spm.alter_sql_plan_baseline
去调整这些参数值。如:
1
|
var temp varchar2(4000)
|
查询基线执行计划:
1
|
SELECT PLAN_TABLE_OUTPUT
|
2.5 发展基线
Plan Evolution(发展基线)就是优化器识别新执行计划(unaccepted)并加入到基线的过程。
创建发展基线的大致步骤(12c):
- Create Evolve Task (dbms_spm.create_evolve_task)
- Execute Evolve Task (dbms_spm.execute_evolve_task)
- Report Evolve Task (dbms_spm.report_evolve_task)
- Accept Recommendation (dbms_spm.accept_sql_plan_baseline)
2.5.1 手工创建发展基线(12c)
- 创建evolve任务
1
|
VARIABLE cnt NUMBER
|
- 执行该任务
1
|
EXECUTE :exe_name :=DBMS_SPM.EXECUTE_EVOLVE_TASK(task_name=>:tk_name);
|
- 查看报告
1
|
EXECUTE :evol_out := DBMS_SPM.REPORT_EVOLVE_TASK( task_name=>:tk_name, execution_name=>:exe_name );
|
- 实施推荐
1
|
EXECUTE :cnt := DBMS_SPM.IMPLEMENT_EVOLVE_TASK( task_name=>:tk_name, execution_name=>:exe_name );
|
2.5.2 手动发展基线(11g)
1
|
var report clob;
|
2.5.3 自动发展基线(12c)
通过SYS_AUTO_SPM_EVOLVE_TASK
可以在12c中自动发展基线,
查看当前自动任务配置信息:
1
|
COLUMN parameter_name FORMAT A25
|
关闭自动任务:
1
|
BEGIN
|
查看自动任务执行结果:
1
|
SET LONG 1000000 PAGESIZE 1000 LONGCHUNKSIZE 100 LINESIZE 100
|
2.6 删除基线
1
|
--指定某一个baseline删除
|
2.7 管理SBM
- 查询当前SBM配置
1
|
SELECT PARAMETER_NAME, PARAMETER_VALUE FROM DBA_SQL_MANAGEMENT_CONFIG;
|
上述结果为默认配置,SBM可使用的空间上限为sysaux的10%,保留期限为53周。
- 修改SBM配置
1
|
--修改空间限制为30%:
|
Reference:
SQL Plan Management with Oracle Database 12c Release 2
Managing SQL Plan Baselines
How to Load SQL Plans into SQL Plan Management (SPM) from the Automatic Workload Repository (AWR) (Doc ID 789888.1)
White Papers and Blog Entries for Oracle Optimizer (Doc ID 1337116.1)
How to Use SQL Plan Management (SPM) - Plan Stability Worked Example (Doc ID 456518.1)
EOF