场景:数据库升级第二天,操作系统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耗尽的更多相关文章

  1. (转) Oracle SQL优化必要的全表扫描思路分析

    大多数情况下,我们需要避免SQL在查询时进行全表扫描(FTS),但是对于必须需要进行全表扫描的情况,也可以进行一些优化处理. 即使全表扫描是检索所需数据的唯一可行方法,仍然有多种方法来提升查询性能.优 ...

  2. oracle优化:避免全表扫描(高水位线)

    如果我们查询了一条SQL语句,这条SQL语句进行了全表扫描,那到底是扫描了多少个数据块呢?是表有多少数据,就扫描多少块吗?不是的.而是扫描高水位线一下的所有块.有的时候有人经常说,我的表也不大呀,怎么 ...

  3. oracle优化:避免全表扫描

    http://blog.csdn.net/onetree2010/article/details/6098259

  4. 【转】避免全表扫描的sql优化

    对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引: .尝试下面的技巧以避免优化器错选了表扫描:· 使用ANALYZE TABLE tbl_name为扫 ...

  5. 避免全表扫描的sql优化

    对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引:  .尝试下面的技巧以避免优化器错选了表扫描: ·   使用ANALYZE TABLE tbl_na ...

  6. SQL 数据优化索引建suo避免全表扫描

    首先什么是全表扫描和索引扫描?全表扫描所有数据过一遍才能显示数据结果,索引扫描就是索引,只需要扫描一部分数据就可以得到结果.如果数据没建立索引. 无索引的情况下搜索数据的速度和占用内存就会比用索引的检 ...

  7. sql语句优化:尽量使用索引避免全表扫描

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  8. Oracle收集对表收集统计信息导致全表扫描直接路径读?

    direct path read深入解析 前言 最近碰到一件很奇葩的事情,因为某条SQL执行缓慢,原因是走了笛卡尔(两组大数据结果集),而且笛卡尔还是NL的一个部分,要循环31M次. 很容易发现是统计 ...

  9. mysql优化器在统计全表扫描的代价时的方法

    innodb 的聚集索引 的叶子结点 存放的 是 索引值以及数据页的偏移量 那么在计算全表扫描的代价是怎么计算的呢? 我们知道代价 为 cpu代价+io代价 cpu代价 就是 每5条记录比对 计算一个 ...

随机推荐

  1. MySQL在DOS界面对database和table增删改查

    昨天新接触MySQL,学习了一些内容,今天过来复习一下.(吐槽一下:安装个MySQL耗费老子半天时间!!) 学习了一下,大概知道了对数据库基本的增删改查,增add,删drop,改alter,查show ...

  2. 简单理解C#中的抽象工厂模式是什么概念!

    抽象工厂模式向客户端提供一个接口,使得客户端在不必指定具体类型的情况下,创建多个产品族中的对象.本文采取的仍然是接着以前的那个快餐店的例子.现在,快餐店经常良好,逐渐发展壮大,为了适合不同地方人的饮食 ...

  3. SpringBoot中Mybaties PageHelper插件使用

    首先引入pom.xml文件配置  <!-- mybatis --> <dependency>  <groupId>org.mybatis.spring.boot&l ...

  4. 解决SQL server2005数据库死锁的经验心得

    前段时间提到的"sql server 2005 死锁解决探索",死锁严重,平均每天会发生一次死锁,在解决和处理SQL server2005死锁中查了很多资料和想了很多办法,后来我们 ...

  5. LINUX系统文件类型分类

    使用LINUX过程中,时常会对文件进行操作.但是linux中文件究竟有哪些分类呢?今天让我们大家来总结一下吧! 概述: linux文件可以分为五种类型,分别为:普通文件.目录.字符设备或块设备.套接口 ...

  6. gdb可视化工具gdbgui

    gdbgui是一款很强大的gdb可视化工具,基于浏览器调试很方便.后台是python写的,目前使用起来还有些bug,不过已经很满足了. 官网 https://gdbgui.com Github htt ...

  7. July 05th 2017 Week 27th Wednesday

    No man can make a good coat with bad cloth. 巧妇难为无米之炊. One can't make bricks without straw. There is ...

  8. UI层实现

    领域驱动设计实践 —— UI层实现   目录 1. User Interface 2. Controller 3.  DTO 4.  infrastructure层的公共组件 5. UI层类图 6. ...

  9. 通讯聊天工具(pingin)

    pidgin需要添加插件才可以进行QQ,msn,facebook等聊天 sudo apt-get install pidgin(ubuntu 可以直接进行安装) sudo add-apt-reposi ...

  10. C# using、namespace使用注意事项

    一.using 用法 1.引用命名空间. 如: using System; 2.自动释放对象使用的资源. 如: using (SqlConnection connection = new SqlCon ...