
SPA(SQL Performance Analysis)是Oracle DBA常用工具,主要用于评估数据库版本升级、参数调整、平台架构变动等重大变更前后的SQL性能对比,其实现原理是将原生产系统的SQL语句打包成SQL集合 – SQL Tuning Set,并在目标环境上进行重放,通过生产和目标环境SQL语句执行计划、SQL执行时间、逻辑读和CPU时间等4个维度的对比,评估SQL语句在目标环境中的执行效率。
但是我们在分析报告的过程中经常会出现如下图的这种现象,(卖个关子,大家先看图后面再解释)。

不知道各位有没有看出来,上图的执行计划其实并没有发生变化,使用的扫描算子是相同的,涉及的表也没有发生变化,但是在两个环境中Plan Hash Value是不同的,在概览中它的Plan Change也是y。

以我的个人习惯,通常会将执行计划没有发生变化的SQL先找出来排除出去,重点分析执行计划变化,且执行频率比较高、对系统整体影响比较大的SQL。那么上面的SQL就会给我们带来不少的麻烦,明明执行计划没有发生变化,Plan Change却是y,难道只能人工确认后再进行排除吗?这样会大大降低我们的分析效率。
针对这个问题,Oracle的给出的解释说这是一个预期的行为,造成这种现象的原因是Oracle中的plan_hash_value值的生成是依赖OS Big/Little endian格式。Linux操作系统通常使用Intel X86或X86-64的处理器,这种处理器是Little endian,而IBM Power,Sun SPARC等小型机处理器则是Big endian格式。因此我们将小型机中抓取的SQL到Linux环境数据库上回放时,生成出来的plan_hash_value不同,SPA报告中默认根据plan_hash_value来判断执行计划是否发生变化,所以会出现执行计划相同但是Plan Change为y的现象。
为了解决这个问题,Oracle在DBMS_SQLPA包中提供了一个参数'PLAN_LINES_COMPARISON',该参数的三个可选值定义如下,将其设置为ALWAYS则通过比对执行计划的每个操作是否相同来判断执行计划是否改变。
ALWAYS --- We do line by line comparison of plans in all scenarios.
AUTO ---- Line by Line comparison of plans only if phv2 is not available and phv1 is different
NONE ---- line by line comparison of plans only if phv is unknown
SPA任务开始前设置该参数为ALWAYS后,再执行SPA任务。
BEGIN
DBMS_SQLPA.SET_ANALYSIS_TASK_PARAMETER(
task_name => 'my_spa_task',
parameter => 'PLAN_LINES_COMPARISON',
value => 'ALWAYS');
END;
/

这次的报告中虽然plan_hash_value仍然不同,但在概览中已经不认为执行计划改变了。

通过这种方式能够将执行计划未发生的语句快速过滤出来,从而大幅提升SPA的分析效率。

写在最后
我在之前的文章中也表述过类似的观点,产品是否成熟的一个判断标注要看是否能够提供足够多的细节来满足实际使用过程中各种各样的需求。而Oracle数据库就是这样的产品,不夸张的说,很多功能只有你想不到的,没有Oracle做不到的。
大家在使用数据库的过程中还发掘到哪些好用的小技巧,欢迎关注留言,一起唠唠!

数据最前线
身边的数据架构师




