另我无语啊,SQL执行计划走错

今天早上以前出过故障的SQL执行计划又走错了。这个SQL并发很大,当时看到满屏的全表扫描SQL运行,哥有点不淡定。
可MB的这个SQL不该走错了。
第一,我用了baseline.

第二,当时我看了全表扫描的cost>>索引的cost.

第三,表的统计信息都有

SQL如下:
SELECT count(*)
  FROM EN_GS_SERV_SERVICE_FDT0 a
/*no open this function*/
WHERE 1 = 1
   and GLOBAL_ID = :1;

统计信息如下:
TABLE_NAME                  NUM_ROWS     BLOCKS AVG_ROW_LEN TO_CHAR(LAST_ANALYZED,'MM/DD/YYYYHH24:
------------------------- ---------- ---------- ----------- --------------------------------------
EN_GS_SERV_SERVICE_FDT0      6760748     250944         258 04/18/2011 10:39:41


COLUMN_NAME          NUM_DISTINCT
-------------------- ------------

GLOBAL_ID                 1000000

索引统计信息如下:
name                                                           NUM_ROWS   distinct LEAF_BLOCKS         cf      level   alfbpkey
------------------------------------------------------------ ---------- ---------- ----------- ---------- ---------- ----------
EN_GS_SERV_SRV_FDT0_GID_IND                                     6755994     121058       16340    6755952          2          1


是的,索引的聚簇因子是非常大,和表行数接近,可关键是这个SQL是count(*)操作,而且谓词只有一个,就是索引的。根本跟聚簇因子半毛钱关系都没有,因为不需要回表。当时虽然万分紧急,还是淡定的看了下走索引的cost,只有3,只有3啊,全表的都过万了,MB的。

出问题的时候,explain plan 出来的默认执行计划是全表扫描
----------------------------------------------------------------------------------------------
| Id  | Operation          | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                         |     1 |     7 | 55226   (1)| 00:11:03 |
|   1 |  SORT AGGREGATE    |                         |     1 |     7 |            |          |
|*  2 |   TABLE ACCESS FULL| EN_GS_SERV_SERVICE_FDT0 |     7 |    49 | 55226   (1)| 00:11:03 |
----------------------------------------------------------------------------------------------

我加了索引的hint,查看cost,只有3
-------------------------------------------------------------------------------------------------
| Id  | Operation         | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                             |     1 |     7 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE   |                             |     1 |     7 |            |          |
|*  2 |   INDEX RANGE SCAN| EN_GS_SERV_SRV_FDT0_GID_IND |     7 |    49 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

更关键的是。这个SQL有baseline。但是当时没用到。这更是让我费解的。
通过如下方法让执行计划失效:
begin
  dbms_stats.set_column_stats(ownname       => 'dhw',
                              tabname       => 'EN_GS_SERV_SERVICE_FDT0',
                              force         => true,
                              colname       => 'GLOBAL_ID',
                              distcnt       => 10000000);
end;
/

重新explain plan for,走对了。而且baseline也自己用上了。
太让我费解了。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22034023/viewspace-696958/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22034023/viewspace-696958/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值