Chinaunix首页 | 论坛 | 博客
  • 博客访问: 527051
  • 博文数量: 128
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 1345
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-22 21:43
文章分类

全部博文(128)

文章存档

2009年(30)

2008年(98)

我的朋友

分类: Oracle

2008-10-20 16:53:09

今天有位同事说,某张表建了索引,而且查询时也走索引,但还是感觉慢,要5秒钟走左才能跑完

看执行计划
select count(*) from phone_number where an_type_cd = 103

SQL> set autotrace traceonly exp;
SQL> set autotrace traceonly exp stat;
SQL> select count(*) from PHONE_NUMBER pn WHERE pn.AN_TYPE_CD = 103;


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1851 Card=1 Bytes=4)
   1    0   SORT (AGGREGATE)
   2    1     INDEX (FAST FULL SCAN) OF 'PHONE_NUMBER_FIR_IDX' (NON-UN
          IQUE) (Cost=1851 Card=1531395 Bytes=6125580)


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      19317  consistent gets
      19283  physical reads
          0  redo size
        404  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

IO读取很高,索引走的是 INDEX (FAST FULL SCAN)
再看一下索引的大小,

select bytes / 1024 / 1024 from user_segments s where s.segment_name = 'PHONE_NUMBER_FIR_IDX';
120M

这样看来,快速索引扫描120M,需要5秒钟,但为什么没有走INDEX(RANGE SCAN),就很奇怪了


因为原有的值AN_TYPE_CD,存储的数据变化不大,共153个变化值
所以在该字段上建bitmap索引

create bitmap index PHONE_NUMBER_FIR_IDX on PHONE_NUMBER(AN_TYPE_CD);

建完后查看索引大小
2M

这样再看select count(*) from PHONE_NUMBER pn WHERE pn.AN_TYPE_CD = 103;
花了0.297秒

表的数据量:phone_number 900W条
select count(*) from PHONE_NUMBER pn WHERE pn.AN_TYPE_CD = 103; 搜索出来的数据量 153条




然后同事又报
SELECT rownum row_id,
       PHONE_NUMBER_ID,
         AN_TYPE_CD,
         RSC_STATUS_CD,
         PG_TRP_FUNCTION.FUN_GETRSCSTATUSNAME(RSC_STATUS_CD) AS RSC_STATUS_CD_NAME,
         AREA_ID,
         PG_TRP_FUNCTION.FUN_GETAREANAME(AREA_ID) AS AREA_NAME,
         NUMBER_ELEMENT_ID,
         PN_LEVEL_ID,
         PHONE_NUMBER,
         TO_CHAR(CREATED_DT, 'YYYY-MM-DD') AS CREATED_DT,
         TO_CHAR(EXP_DT, 'YYYY-MM-DD') AS EXP_DT,
         TO_CHAR(VERSION, 'YYYY-MM-DD') AS VERSION,
         USE_WAY,
         CREATED_STAFF_ID
      FROM(
       SELECT * FROM PHONE_NUMBER
        WHERE AN_TYPE_CD = 103 order by CREATED_DT desc
       )where rownum >=1;

执行得相当慢

再看执行计划,
SELECT STATEMENT, GOAL = CHOOSE            104748    1531395    218989485    104748
 COUNT                        
  FILTER                        
   VIEW    RM        104748    1531395    218989485    
    SORT ORDER BY            104748    1531395    108729045    104748
     TABLE ACCESS FULL    RM    PHONE_NUMBER    8796    1531395    108729045    8796

使用的是全表扫描
加上暗示/*+INDEX(PHONE_NUMBER PHONE_NUMBER_FIR_IDX)*/


SELECT rownum row_id,
       PHONE_NUMBER_ID,
         AN_TYPE_CD,
         RSC_STATUS_CD,
         PG_TRP_FUNCTION.FUN_GETRSCSTATUSNAME(RSC_STATUS_CD) AS RSC_STATUS_CD_NAME,
         AREA_ID,
         PG_TRP_FUNCTION.FUN_GETAREANAME(AREA_ID) AS AREA_NAME,
         NUMBER_ELEMENT_ID,
         PN_LEVEL_ID,
         PHONE_NUMBER,
         TO_CHAR(CREATED_DT, 'YYYY-MM-DD') AS CREATED_DT,
         TO_CHAR(EXP_DT, 'YYYY-MM-DD') AS EXP_DT,
         TO_CHAR(VERSION, 'YYYY-MM-DD') AS VERSION,
         USE_WAY,
         CREATED_STAFF_ID
      FROM(
       SELECT /*+INDEX(PHONE_NUMBER PHONE_NUMBER_FIR_IDX)*/ * FROM PHONE_NUMBER
        WHERE AN_TYPE_CD = 103 order by CREATED_DT desc
       )where rownum >=1;
       
      
SELECT STATEMENT, GOAL = CHOOSE            132622    1531395    218989485    132622
 COUNT                       
  FILTER                       
   VIEW    RM        132622    1531395    218989485   
    SORT ORDER BY            132622    1531395    108729045    132622
     TABLE ACCESS BY INDEX ROWID    RM    PHONE_NUMBER    36669    1531395    108729045    36669
      BITMAP CONVERSION TO ROWIDS                       
       BITMAP INDEX SINGLE VALUE    RM    PHONE_NUMBER_FIR_IDX               

走位图索引,执行相当的快0.5秒

影响:
索引的类型和走的方式对于扫描数据来说,有相当大的影响,这个需要注意
阅读(1280) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~