记录一次没有收集直方图优化器选择全表扫描导致CPU耗尽
场景:数据库升级第二天,操作系统CPU使用率接近100%。
查看ash报告:

再看TOP SQL

具体SQL:
select count(1) as chipinCount, sum(bets) as sumBets from t_chipin_temp where status in (0) and lottype='gp'
看到这个sql的执行计划走全表扫描。再查看相关列上是否有索引,结果是有索引的。那么问题来了,既然有索引,而且升级之后对该表格还进行过基本的统计信息收集,那么为什么优化器没有走索引。

收集该sql的10053事件
SQL> select child_number from v$sql where sql_id='57tdrj6a4ync4';
CHILD_NUMBER
------------
0
SQL> execute DBMS_SQLDIAG.DUMP_TRACE(p_sql_id=>'57tdrj6a4ync4', p_child_number=>0, p_component=>'Optimizer', p_file_id=>'SQL_TRACE_10053');
PL/SQL procedure successfully completed.
SQL> SELECT value FROM v$diag_info WHERE name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/orcl11g/ORCL/trace/ORCL_ora_32070_SQL_TRACE_10053.trc
vi /u01/app/oracle/diag/rdbms/orcl11g/ORCL/trace/ORCL_ora_32070_SQL_TRACE_10053.trc
Access path analysis for T_CHIPIN_TEMP
***************************************
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for T_CHIPIN_TEMP[T_CHIPIN_TEMP]
Column (#8): STATUS(
AvgLen: 4 NDV: 4 Nulls: 0 Density: 0.250000 Min: -2 Max: 4
Column (#44): lottype(
AvgLen: 3 NDV: 2 Nulls: 0 Density: 0.500000
ColGroup (#4, Index) TX_CHIPIN_TMP_TIMCODE2
Col#: 5 11 31 33 CorStregth: -1.00
ColGroup (#2, Index) IDX_T_CHIPIN_TEMP
Col#: 13 34 44 CorStregth: -1.00
ColGroup (#3, Index) TX_CHIPIN_TMP_TIME2
Col#: 8 20 44 CorStregth: -1.00
ColGroup (#5, Index) TX_CHIPIN_TMP_AWARD2
Col#: 15 35 36 CorStregth: -1.00
ColGroup (#6, Index) IX_CHIPIN_TEMP_STALOC2
Col#: 8 44 CorStregth: 2.67
ColGroup (#1, Index) IDX_S_P
Col#: 8 31 CorStregth: -1.00
ColGroup Usage:: PredCnt: 2 Matches Full: #6 Partial: Sel: 0.3420
Table: T_CHIPIN_TEMP Alias: T_CHIPIN_TEMP
Card: Original: 5671105.00 Rounded: 1939622 Computed: 1939621.71 Non Adjusted: 1939621.71
原始行数 近似值 精确值 非修正值
Access Path: TableScan
Cost: 62160.58 Resp: 62160.58 Degree: 0
Cost_io: 61966.00 Cost_cpu: 7711574370
Resp_io: 61966.00 Resp_cpu: 7711574370
kkofmx: index filter:"T_CHIPIN_TEMP"."lottype"=:B1
kkofmx: index filter:"T_CHIPIN_TEMP"."STATUS"=:B1
kkofmx: index filter:"T_CHIPIN_TEMP"."lottype"=:B1
Access Path: index (RangeScan)
Index: IDX_S_P
resc_io: 918156.00 resc_cpu: 8328403927
ix_sel: 0.250000 ix_sel_with_filters: 0.250000
Cost: 918366.14 Resp: 918366.14 Degree: 1
Access Path: index (skip-scan)
SS scan sel: 0.500000 SS filter sel: 0.500000 ANDV (#skips): 564.000000
SS io: 14684.000000 vs. table scan io: 61966.000000
Skip Scan chosen
Access Path: index (SkipScan)
Index: IDX_T_CHIPIN_TEMP
resc_io: 226050.00 resc_cpu: 5276879027
ix_sel: 0.500000 ix_sel_with_filters: 0.500000
Cost: 226183.15 Resp: 226183.15 Degree: 1
ColGroup Usage:: PredCnt: 2 Matches Full: #6 Partial: Sel: 0.3420
ColGroup Usage:: PredCnt: 2 Matches Full: #6 Partial: Sel: 0.3420
Access Path: index (AllEqRange)
Index: IX_CHIPIN_TEMP_STALOC2
resc_io: 128169.00 resc_cpu: 3259690463
ix_sel: 0.350930 ix_sel_with_filters: 0.350930
Cost: 128251.25 Resp: 128251.25 Degree: 1
ColGroup Usage:: PredCnt: 2 Matches Full: #6 Partial: Sel: 0.3420
Access Path: index (skip-scan)
SS scan sel: 0.344312 SS filter sel: 0.344312 ANDV (#skips): 1579520.000000
SS io: 20452.000000 vs. table scan io: 61966.000000
Skip Scan chosen
Access Path: index (SkipScan)
Index: TX_CHIPIN_TMP_TIME2
resc_io: 1157882.00 resc_cpu: 10592729810
ix_sel: 0.344312 ix_sel_with_filters: 0.344312
Cost: 1158149.27 Resp: 1158149.27 Degree: 1
****** trying bitmap/domain indexes ******
****** finished trying bitmap/domain indexes ******
******** Begin index join costing ********
****** trying bitmap/domain indexes ******
ColGroup Usage:: PredCnt: 2 Matches Full: #6 Partial: Sel: 0.3420
ColGroup Usage:: PredCnt: 2 Matches Full: #6 Partial: Sel: 0.3420
ColGroup Usage:: PredCnt: 2 Matches Full: #6 Partial: Sel: 0.3420
Access Path: index (AllEqRange)
Index: IX_CHIPIN_TEMP_STALOC2
resc_io: 4610.00 resc_cpu: 420754238
ix_sel: 0.350930 ix_sel_with_filters: 0.350930
Cost: 4620.62 Resp: 4620.62 Degree: 0
Bitmap nodes:
Used IX_CHIPIN_TEMP_STALOC2
Cost = 4627.223361, sel = 0.342018
****** finished trying bitmap/domain indexes ******
******** End index join costing ********
Best:: AccessPath: TableScan
Cost: 62160.58 Degree: 1 Resp: 62160.58 Card: 1939621.71 Bytes: 0
***************************************
10053中看到因为没有直方图存在,所以这里的Column (#8) Density = 0.25 ,Column (#44) Density = 0.5 是从 1/ NDV 算得的,统计信息显示的status in (0) 数据行占总行数的1/4, lottype='gp' 数据行占总行数的1/2, 所以优化器选择做全表扫描.
SQL> select count(1) as chipinCount, sum(bets) as sumBets from t_chipin_temp where status in (0) and lottype='gp' ;
CHIPINCOUNT SUMBETS
----------- ---------
3 20
以上符合status in (0) and lottype='gp'的只有3行,且status, lottype列上建有复合索引,索引是IX_CHIPIN_TEMP_STALOC2,同时也使用了dbms_stats包收集表和索引上的统计信息,照理说CBO应该选择 INDEX RANGE SCAN,而避免全表扫描,但实时上优化器opitimizer仍然全表扫描。
经过一番查阅,发现其原因是在收集统计信息时并没有收集到直方图,只要收集了直方图,那么优化器就会了解到status in (0) and lottype='gp' 条件仅有少量的行,优化器会走索引。
于是重新收集统计信息加上直方图:
execute dbms_stats.gather_table_stats(ownname => 'USER',tabname => 'T_CHIPIN_TEMP' ,method_opt => 'FOR ALL COLUMNS SIZE 2' ,cascade => true);
alter system flush shared_pool;
执行完以上操作后,系统CPU很快降了下来。
再看执行计划,便是 INDEX RANGE SCAN 了。

再看收集直方图之后10053的内容:
Access path analysis for T_CHIPIN_TEMP
***************************************
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for T_CHIPIN_TEMP[T_CHIPIN_TEMP]
Column (#8):
NewDensity:0.000180, OldDensity:0.000000 BktCnt:5558, PopBktCnt:5558, PopValCnt:3, NDV:3
Column (#8): STATUS(
AvgLen: 4 NDV: 3 Nulls: 0 Density: 0.000180 Min: -2 Max: 4
Histogram: Freq #Bkts: 3 UncompBkts: 5558 EndPtVals: 3
Column (#44):
NewDensity:0.000090, OldDensity:0.000000 BktCnt:5559, PopBktCnt:5558, PopValCnt:1, NDV:2
Column (#44): lottype(
AvgLen: 3 NDV: 2 Nulls: 0 Density: 0.000090
Histogram: Freq #Bkts: 2 UncompBkts: 5559 EndPtVals: 2
ColGroup (#5, Index) TX_CHIPIN_TMP_TIMCODE2
Col#: 5 11 31 33 CorStregth: -1.00
ColGroup (#6, Index) TX_CHIPIN_TMP_AWARD2
Col#: 15 35 36 CorStregth: -1.00
ColGroup (#4, Index) TX_CHIPIN_TMP_TIME2
Col#: 8 20 44 CorStregth: -1.00
ColGroup (#3, Index) IDX_T_CHIPIN_TEMP
Col#: 13 34 44 CorStregth: -1.00
ColGroup (#1, Index) IX_CHIPIN_TEMP_STALOC2
Col#: 8 44 CorStregth: 2.00
ColGroup (#2, Index) IDX_S_P
Col#: 8 31 CorStregth: -1.00
ColGroup Usage:: PredCnt: 2 Matches Full: Partial:
Table: T_CHIPIN_TEMP Alias: T_CHIPIN_TEMP
Card: Original: 5682253.000000 Rounded: 1 Computed: 0.18 Non Adjusted: 0.18
Access Path: TableScan
Cost: 62159.09 Resp: 62159.09 Degree: 0
Cost_io: 61966.00 Cost_cpu: 7652553546
Resp_io: 61966.00 Resp_cpu: 7652553546
kkofmx: index filter:"T_CHIPIN_TEMP"."lottype"='gp'
kkofmx: index filter:"T_CHIPIN_TEMP"."STATUS"=1
kkofmx: index filter:"T_CHIPIN_TEMP"."lottype"='gp'
Access Path: index (RangeScan)
Index: IDX_S_P
resc_io: 667.00 resc_cpu: 6041476
ix_sel: 0.000180 ix_sel_with_filters: 0.000180
Cost: 667.15 Resp: 667.15 Degree: 1
Access Path: index (skip-scan)
SS scan sel: 0.000180 SS filter sel: 0.000180 ANDV (#skips): 564.000000
SS io: 14379.000000 vs. table scan io: 61966.000000
Skip Scan chosen
Access Path: index (SkipScan)
Index: IDX_T_CHIPIN_TEMP
resc_io: 14450.00 resc_cpu: 104195010
ix_sel: 0.000180 ix_sel_with_filters: 0.000180
Cost: 14452.63 Resp: 14452.63 Degree: 1
ColGroup Usage:: PredCnt: 2 Matches Full: Partial:
ColGroup Usage:: PredCnt: 2 Matches Full: Partial:
Access Path: index (AllEqRange)
Index: IX_CHIPIN_TEMP_STALOC2
resc_io: 4.00 resc_cpu: 29696
ix_sel: 0.000000 ix_sel_with_filters: 0.000000
Cost: 4.00 Resp: 4.00 Degree: 1
ColGroup Usage:: PredCnt: 2 Matches Full: Partial:
Access Path: index (skip-scan)
SS scan sel: 0.000000 SS filter sel: 0.000000 ANDV (#skips): 1582976.000000
SS io: 20631.000000 vs. table scan io: 61966.000000
Skip Scan chosen
Access Path: index (SkipScan)
Index: TX_CHIPIN_TMP_TIME2
resc_io: 20634.00 resc_cpu: 146945003
ix_sel: 0.000000 ix_sel_with_filters: 0.000000
Cost: 20637.71 Resp: 20637.71 Degree: 1
****** trying bitmap/domain indexes ******
****** finished trying bitmap/domain indexes ******
******** Begin index join costing ********
****** trying bitmap/domain indexes ******
ColGroup Usage:: PredCnt: 2 Matches Full: Partial:
ColGroup Usage:: PredCnt: 2 Matches Full: Partial:
ColGroup Usage:: PredCnt: 2 Matches Full: Partial:
Access Path: index (AllEqRange)
Index: IX_CHIPIN_TEMP_STALOC2
resc_io: 3.00 resc_cpu: 21564
ix_sel: 0.000000 ix_sel_with_filters: 0.000000
Cost: 3.00 Resp: 3.00 Degree: 0
Bitmap nodes:
Used IX_CHIPIN_TEMP_STALOC2
Cost = 3.000545, sel = 0.000000
****** finished trying bitmap/domain indexes ******
******** End index join costing ********
Best:: AccessPath: IndexRange
Index: IX_CHIPIN_TEMP_STALOC2
Cost: 4.00 Degree: 1 Resp: 4.00 Card: 0.18 Bytes: 0
从10053可以看出手动指定收集直方图后CBO优化器才能做出正确的选择
注:dbms_stats的自动决定直方图的收集与否及收集的桶数受到col_usage$表影响,如果某张表的列存在于col_usage$中,oracle就认为该列存在收集直方图的必要。
Histograms are not gathered on columns for which there is no predicate information captured in the col_usage$ view. Col_usage$ is populated with the column information only when queries are executed with columns referred in predicate information.
记录一次没有收集直方图优化器选择全表扫描导致CPU耗尽的更多相关文章
- (转) Oracle SQL优化必要的全表扫描思路分析
大多数情况下,我们需要避免SQL在查询时进行全表扫描(FTS),但是对于必须需要进行全表扫描的情况,也可以进行一些优化处理. 即使全表扫描是检索所需数据的唯一可行方法,仍然有多种方法来提升查询性能.优 ...
- oracle优化:避免全表扫描(高水位线)
如果我们查询了一条SQL语句,这条SQL语句进行了全表扫描,那到底是扫描了多少个数据块呢?是表有多少数据,就扫描多少块吗?不是的.而是扫描高水位线一下的所有块.有的时候有人经常说,我的表也不大呀,怎么 ...
- oracle优化:避免全表扫描
http://blog.csdn.net/onetree2010/article/details/6098259
- 【转】避免全表扫描的sql优化
对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引: .尝试下面的技巧以避免优化器错选了表扫描:· 使用ANALYZE TABLE tbl_name为扫 ...
- 避免全表扫描的sql优化
对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引: .尝试下面的技巧以避免优化器错选了表扫描: · 使用ANALYZE TABLE tbl_na ...
- SQL 数据优化索引建suo避免全表扫描
首先什么是全表扫描和索引扫描?全表扫描所有数据过一遍才能显示数据结果,索引扫描就是索引,只需要扫描一部分数据就可以得到结果.如果数据没建立索引. 无索引的情况下搜索数据的速度和占用内存就会比用索引的检 ...
- sql语句优化:尽量使用索引避免全表扫描
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- Oracle收集对表收集统计信息导致全表扫描直接路径读?
direct path read深入解析 前言 最近碰到一件很奇葩的事情,因为某条SQL执行缓慢,原因是走了笛卡尔(两组大数据结果集),而且笛卡尔还是NL的一个部分,要循环31M次. 很容易发现是统计 ...
- mysql优化器在统计全表扫描的代价时的方法
innodb 的聚集索引 的叶子结点 存放的 是 索引值以及数据页的偏移量 那么在计算全表扫描的代价是怎么计算的呢? 我们知道代价 为 cpu代价+io代价 cpu代价 就是 每5条记录比对 计算一个 ...
随机推荐
- Java中的深拷贝和浅拷贝(转载)
深拷贝(深复制)和浅拷贝(浅复制)是两个比较通用的概念,尤其在C++语言中,若不弄懂,则会在delete的时候出问题,但是我们在这幸好用的是Java.虽然java自动管理对象的回收,但对于深拷贝(深复 ...
- OpenfileDialog选择照片的简单应用
OpenFileDialog openFileDlg = new OpenFileDialog(); openFileDlg.Title = "选择文件"; openFileDlg ...
- 致 BitClub 矿池,你们为什么要对比特币网络发动交易延展性攻击?
原文:https://medium.com/@bithernet/bitclub-why-are-you-doing-malleability-attack-now-6faa194b2146#.v4y ...
- tomcat启动很慢 停留在 At least one JAR was scanned for TLDs yet contained no TLDs.
部署项目时候,发现启动特别慢,要等好几分钟,这不正常啊.然后每次部署都停留在 At least one JAR was scanned for TLDs yet contained no TLDs. ...
- Java—IO流 字节流
IO流(输入流.输出流),又分为字节流.字符流. 流是磁盘或其它外围设备中存储的数据的源点或终点. 输入流:程序从输入流读取数据源.数据源包括外界(键盘.文件.网络…),即是将数据源读入到程序的通信通 ...
- writing a javascript module ready for ES6 import
javascript模块化是一个比较大也是比较容易混淆的topic.通常几乎所有的第三方Library都支持CMD,AMD,ES6,Global object方式来引用lib所暴露出来的服务. 那么如 ...
- calculate fraction by oracle
QUESTION:When you meet calculate fraction in oracle SOLUTION: 1.Check out their values respectively. ...
- 启动入口Start.java分析
框架的启动器在包:org.ofbiz.base.start 入口为:Start.java的main方法 Start.java启动器内容: 步骤 详情 入参校验 help/status/shutdown ...
- 设计模式:访问者(Visitor)模式
设计模式:访问者(Visitor)模式 一.前言 什么叫做访问,如果大家学过数据结构,对于这点就很清晰了,遍历就是访问的一般形式,单独读取一个元素进行相应的处理也叫作访问,读取到想要查看的内容+ ...
- spring core
https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#beans