SQL执行计划异常引起的性能问题

 

故障类型

直方图引起的 sql 执行计划异常

 

现象错误号

业务某个模块单条 SQL 执行非常慢,执行时间是原来的好几倍。问题表格对应的列上存在直方图导致执行计划偏差,默认情况下未特殊指定列的直方图是收集的。

 

故障描述

直方图 (Histogram) 又称质量分布图。是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况。可以看出,直方图可以用来描述数据分布的情况。 Oracle 中也是如此,直方图可以准确预测列数据的分布,尤其在出现数据分布倾斜的情况下,通过直方图信息,可以选择最优的执行计划。

此处由于 account_no 值为 3301040160005763134 数量级较大, Oracle CBO 结合 account_no 列上的直方图计算误认为走全表执行计划最优。因而采用了全表扫的方式,最终导致执行性能下降。

例如,如果一到两个值构成了表中的大部分数据 ( 数据偏斜 ) ,相关的索引就可能无法帮助减少满足查询所需的 I/O 数量。创建直方图可以让基于成本的优化器知道何时使用索引才最合适,或何时应该根据 WHERE 子句中的值返回表中 80 %的记录。

 

故障原因分析

问题 sql 语句:

SELECT serial_no,

       area_code,

       acc_area,

       trans_area,

       trans_state,

       account_no,

       group_sub_no,

       gl_class,

       product_code,

       cur_type,

       TO_CHAR(acc_date, :"SYS_B_0"),

       TO_CHAR(acc_time, :"SYS_B_1"),

       TO_CHAR(sys_date, :"SYS_B_2"),

       TO_CHAR(sys_time, :"SYS_B_3"),

       main_code,

       process_code,

       acc_reason,

       detail_serial,

       debit_amt,

       credit_amt,

       balance,

       pre_balance,

       account_jnls_no,

       trans_jnls_no,

       refer_trans_no,

       account_cycle_no,

       clearing_times,

       related_cycle_no,

       TO_CHAR(related_acc_date, :"SYS_B_4"),

       cash_flag,

       remote_flag,

       d_c_flag,

       trans_flag,

       summary,

       summary_rem,

       voucher_type,

       voucher_no,

       oper_no,

       check_oper,

       terminal_no,

       channel_code,

       party_type,

       party_account,

       party_name,

       party_bank,

       party_bank_name,

       remark,

       print_flag,

       dac

  FROM account_detail

 WHERE account_no = :account_no__0

   AND detail_serial >= :detail_serial__GE_1

 ORDER BY detail_serial;

sql 语句上来看 account_no detail_serial 列上存在联合索引选择性较好。

进一步排查数据库中记录的执行信息。

 

 

SQL 244saaz6znbwf 的执行计划来看存在两个 hash 3084482491 3788272203 ,其中值为 3788272203 相对于 3084482491 执行计划更好一点,单条 SQL 执行时间只有 0.1 秒。


查看 SQL 244saaz6znbwf 历史执行计划

SQL 244saaz6znbwf 12 1 日的历史执行计划来看并不稳定时好时坏,询问后发现根据带入的值不同执行时间也有很大偏差,其中当 account_no 带入值为 3301040160005763134 时相应特别慢十几分钟都不出结果,此时本能反应统计信息不准确或 account_no 上存在直方图导致执行计划不稳定,进一步排查。

查看表格 account_detail 统计信息

select to_char(LAST_ANALYZED,'yyyy-mm-dd hh24:mi:ss'),NUM_ROWS,TABLE_NAME FROM DBA_TABLES WHERE TABLE_NAME='ACCOUNT_DETAIL';

 

LAST_ANALYZED       NUM_ROWS TABLE_NAME

------------------------------------------------- ----------

2017-12-01 1:34:47   342547333 ACCOUNT_DETAIL

表格 account_detail 统计更新正常,排除统计信息问题,进一步排查柱状图

查看表格 account_detail 列直方图信息

select column_name,density,num_buckets,histogram from dba_tab_col_statistics where table_name='ACCOUNT_DETAIL' and

column_name in ('ACCOUNT_NO','DETAIL_SERIAL');

 

COLUMN_NAME        DENSITY NUM_BUCKETS HISTOGRAM

--------------- ---------- ----------- ---------------

ACCOUNT_NO      .000283849         254 HEIGHT BALANCED

DETAIL_SERIAL   .000204876         254 HEIGHT BALANCED


可以看到 account_no 列直方图并非为空,而且值为 3301040160005763134 bucket 数较多数量级是别的值的好几倍。这也刚好印证了 account_no 带入其他值时执行效率正常,而带入 3301040160005763134 时几乎无响应。此时可以判断是由于 account_no 列上存在直方图导致执行计划偏差,默认情况下未特殊指定列的直方图是收集的。

直方图 (Histogram) 又称质量分布图。是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况。可以看出,直方图可以用来描述数据分布的情况。 Oracle 中也是如此,直方图可以准确预测列数据的分布,尤其在出现数据分布倾斜的情况下,通过直方图信息,可以选择最优的执行计划。

此处由于 account_no 值为 3301040160005763134 数量级较大 Oracle CBO 结合 account_no 列上的直方图计算误认为走全表执行计划最优。因而采用了全表扫的方式,最终导致执行性能下降。

例如,如果一到两个值构成了表中的大部分数据 ( 数据偏斜 ) ,相关的索引就可能无法帮助减少满足查询所需的 I/O 数量。创建直方图可以让基于成本的优化器知道何时使用索引才最合适,或何时应该根据 WHERE 子句中的值返回表中 80 %的记录。

 


请使用浏览器的分享功能分享到微信等