【Oracle】看懂执行计划系列之稳定执行计划
Oracle Hint
Oracle Hints是一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划,它允许用户在SQL语句中插入相关的语法,从而影响SQL的执行方式。
Hint的作用
- 调整目标SQL使用的优化器类型
- 调整优化器的优化目标
- 调整表的访问路径
- 调整表的连接类型
- 调整表的连接顺序
- 提高语句的并行程度
Hint的弊端
- Hint是比较"暴力"的一种解决方式,不是很优雅。需要开发人员手工修改代码。
- Hint不会去适应新的变化,只是在现有的基础上产生更优的执行计划。
- Hint随着数据库版本的变化,可能会有一些差异、甚至废弃的情况。
Oracle stored outline
Oracle stored outline(存储提纲)是最早的基于提示来控制SQL执行计划的机制,也是9i以及之前版本唯一可以用来稳定和控制SQL执行计划的工具。主要的作用是用来保持固定sql语句的执行计划,让sql语句的执行计划在数据库环境变更(统计信息、优化器参数、表结果变更等)后还能保持原来的执行计划。
使用场景
- 避免SQL的执行计划在统计数据不准确的情况(如未能及时收集表或索引的统计信息)下导致变化从而引起的性能降低。
- 避免容易因为Bind Peeking导致SQL执行计划变差从而引起的性能降低。
- 避免大规模分布实施的应用出现数据库版本、配置等区别引起的优化器产生不同的执行计划。
注意事项
- 从10g以后,outline基本已经被Oracle废弃并且不在维护。
- 只有设置use_stored_outlines参数后才能启用outline。
- 创建outline需要create any outline or execute_catelog_role权限 。
SQL Profile
SQL Profile是stored outline的进化版,是为目标SQL提供除了统计信息之外的其他信息,比如运行环境、更准确的执行路径等,以帮助优化器为SQL语句选择更合适的执行计划。
优点
- 更容易生成、更改和控制
- 适用范围广
- 在不改变目标SQL文本的情况下达到稳定执行计划的效果
类型
- Automatic类型的SQL Profile
Automatic类型的SQL Profile其实是目标SQL一些额外的调整信息,这些信息存储在数据字典中。Oracle会使用类似于动态采样的方法来支持Automatic类型的SQL Profile,在生成执行计划的时候Oracle会将调整信息同原SQL的相关统计信息等内容一起作用从而得到最新的执行计划 - Manual类型的SQL Profile
Manual类型SQL Profile的本质是一堆来源Outline Data部分的Hint组合,可以在不改变目标SQL文本的情况下调整其执行计划
说明
SQL Profile 实际上只是一种亡羊补牢、被动的技术手段,应用在那些执行计划已经发生了不好的变更的 SQL上,即当我们发现这些SQL的执行计划已经出了问题时通过创建SQL Pofle来纠正、稳定这些SQL的执行计划。也就是说,即便通过创建SQLProfile解决了目标SQL执行计划变更的问题,依然不能保证系统后续执行的 SQL 的执行计划就不再发生不好的变更。
SPM(SQL Plan Management)
SPM 是一种主动的稳定执行计划的手段,能够保证只有被验证过的执行计划才会被启用。SPM既能够主动地稳定执行计划,又保留了继续使用新的执行效率可能更高的执行计划的机会。 SPM启动后,每个SQL的所有执行计划都有对应的SQL Plan Baseline,可以通过DBA_SQL_PLAN_BASELINE查看。只有DBA_SQL_PLAN_BASELINE表中ENABLE和ACCEPTED列的值均为'YES'的SQL Plan Baseline对应的执行计划才会被Oracle启用。
获取方法
- 自动捕获(Automatic Initial Plan Capture)
- 设置OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES = Ture
- Oracle自动监控执行两次以上的SQL语句,将执行计划记入Plan History。
- 生成的第一个执行计划被标记为ENABLED并且是ACCEPTED,后续的执行计划会被标记为ENABLED但不是ACCEPTED。
- 后续如果关闭了自动捕捉,针对存在baseline的SQL,仍旧会有新的PLAN生成,新的Plan仍会进入Plan History,标记为ENABLED但不是ACCEPTED。
- 手动导入(Manual Plan Capture)
Oracle支持通过DBMS_SPM包手动管理SPM,可以将SQL执行计划从高速缓存或现有的SQL优化集中加载到SPM。