一、基础概念
Oracle 11g开始,提供了一种新的固定执行计划的方法,即SQL plan baseline,中文名sql执行计划基线(简称基线),可以认为是OUTLINE(大纲)或者SQL PROFILE的改进版本,基本上它的主要作用可以归纳为如下两个:
1、稳定给定SQL语句的执行计划,防止执行环境或对象统计信息等等因子的改变对SQL语句的执行计划产生影响!
2、减少数据库中出现SQL语句性能退化的概率,理论上不允许一条语句切换到一个比已经执行过的执行计划慢很多的新的执行计划上!
注意:
1、从Oracle的发展角度来看,估计这种方法是Oracle发展和改进的方向,如今outline已经被废弃,sql profile估计在后续的发行版本中也难有改进,因此,对于从11g开始接触Oracle的朋友来说,一定要对sql计划基线有所了解,因为这是以后的主流!
2、SQL执行计划基线保存在数据字典中,查询优化器会自动判断使用他们。
二、工作机制
从Oracle 11g开始,由于基线的存在,一条语句的解析过程大概如下:
- SQL语句被硬解析后,CBO(优化器)会产生很多个的执行计划,CBO从中选择一个成本最低执行计划。
- 基于SQL语句的文本形成一个哈希值(signature),通过这个哈希值来检查数据字典中是否存在同样的基线。
- 如果基线存在,优化器会对刚刚产生的执行计划和保存在SQL plan baseline中的执行计划进行比较。
- 如果基线中有与CBO刚产生的执行计划的匹配的SQL执行计划存在,并且被标记为可接受(‘accepted’),则这个CBO生成的执行计划被启用。
- 如果基线中没有匹配的SQ执行计划存在,CBO评估基线中被标记为‘accepted’的的多个执行计划,并选择其中cost最低的执行计划。(注意,一个语句的基线可以有多个执行计划被保存,这是与其他Outline和SQL profiel都不同的地方)
- 如果刚刚硬解析过程中CBO选择的执行计划比保存在基线中的执行计划COST都低,这个新生成的执行计划被标记为‘not-accepted’并保存在基线中。直到这个执行计划被演化且验证后才会被考虑使用,即标记为accepted(演化和验证,可以简单理解为Oracle确认这个执行计划可以带来更好的性能)。
Oracle 就是通过上面这种方式来确保SQL语句的性能不会退化(即第一部分中我归纳的第二个主要作用),称为“执行计划保守选择策略”
三、创建基线的几种方式
1、自动捕获基线,通过将optimizer_cature_sql_plan_baselines设置为true,优化器为重复执行两次以上的SQL语句生成并保存基线(可以系统级或会话级修改)
2、从SQL调优集合中加载,通过使用包dbm来从SQL调优集合中加载基线
DECLARE
l_plans_loaded PLS_INTEGER;
BEGIN
l_plans_loaded := DBMS_SPM.load_plans_from_sqlset(
sqlset_name => 'my_sqlset');
END;
/
3、从库缓存中加载,通过包dbm函数为一条已经在游标缓存中的语句创建基线
DECLARE
l_plans_loaded PLS_INTEGER;
BEGIN
l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(sql_id => '1fkh93md0802n',plan_hash_value=>null);
END;
/
备注:可以有多种方式加载,例如可以根据sql文本进行模糊匹配、SQL语句解析的用户名等等方式。
四、基线的几种状态
一个SQL语句对应的基线,我将它们归纳为三种状态
- accepted(可接受),只有这种状态的基线,优化器才会考虑此基线中的执行计划
- no-accepted(不可接受),这种状态的基线,优化器在SQL语句解析期间不会考虑。这种状态的基线必须通过演化和验证通过后,转变为accepted状态后,才会被优化器考虑使用
- fixed为yes(固定),这种状态的基线固有最高优先级!比其他两类基线都要优先考虑
五、查看基线
1、基本视图:dba_sql_plan_baselines、dba_sql_management_config
2、底层视图:sqlobj$data 、 sqlobj$ (保存具体的hint),如下查看基线中保存的执行计划语句:
select extractvalue(value(d), '/hint') as outline_hints
from xmltable('/outline_data/hint'
passing ( select xmltype(comp_data) as xmlval
from sqlobj$data sod, sqlobj$ so
where =
and =
and comp_data is not null
and name like '&baseline_plan_name')) d;
3、通过函数来查看基线的详细信息:
select * from table(sql_handle=>'SYS_SQL_11bcd50cd51504e9',plan_name=>'SQL_PLAN_13g6p1maja1790cce5f0e'));
篇幅有限,关于SQL执行计划基线就介绍到这了,后期会分享更多DBA和devops内容,感兴趣的朋友可以关注下!
1.文章《〔oracle执行计划怎么看〕oracle数据库执行计划怎么看!》援引自互联网,为网友投稿收集整理,仅供学习和研究使用,内容仅代表作者本人观点,与本网站无关,侵删请点击页脚联系方式。
2.文章《〔oracle执行计划怎么看〕oracle数据库执行计划怎么看!》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
相关推荐
- . 现代买票为什么带上携程保险
- . 潮阳怎么去广州南站
- . 湖南马拉河怎么样
- . 烧纸为什么到三岔路口
- . 百色为什么这么热
- . 神州租车怎么样
- . 芜湖方特哪个适合儿童
- . 护肤品保养液是什么类目
- . 早晚的护肤保养有哪些项目
- . 女孩护肤品怎么保养的最好