zoukankan      html  css  js  c++  java
  • ITPUB:分区表,每次查询取出1%的记录,为什么没有走索引?

    分区表,每次查询取出1%的记录,为什么没有走索引?

    目前情况:
    windows2003系统, 11gR1版本。
    经常执行的是类似:select * from rece where gpsdate >= ... and gpsdate<=... and device_number=... ; 的查询,即:查询某个设备号的设备,在某些天内的记录。而rece表里共有3亿条记录。
    所以,
    1, 设计rece为分区表,其中的gpsdate上建立了list分区,每天的数据放入一个list分区内。每个分区的记录约为300万行。
    2, 在device_number 列上,建立局部索引,
    create index idx_rece_device_number on rece(device_number) local ;
    通过 SELECT segment_name, partition_name, tablespace_name
    FROM user_segments
    WHERE segment_name = 'IDX_rece_DEVICE_NUMBER'; 可以看到,device_number 列上已经建立了分区索引了。
    但是,却发现执行 select * from rece where gpsdate >= '20100501' and gpsdate<='2010
    0504' and device_number='900000015' ;语句时,默认不走索引?只有加hint后,才走索引,搞不清楚什么原因?
    不明白的原因是:gpsdate是分区的列,而 device_number 列上确实已经有了local索引,为什么 默认还不走索引呢?
    具体的trace信息如下:
    SQL> set autotrace traceonly;
    SQL> select * from rece where gpsdate >= '20100501' and gpsdate<='2010
    0504' and device_number='900000015' ;
    已选择146663行。
    执行计划
    ----------------------------------------------------------
    Plan hash value: 2550857439
    --------------------------------------------------------------------------------
    -----------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Tim
    e | Pstart| Pstop |
    --------------------------------------------------------------------------------
    -----------------------
    | 0 | SELECT STATEMENT | | 170K| 16M| 92991 (1)| 00:
    18:36 | | |
    | 1 | PARTITION LIST ITERATOR| | 170K| 16M| 92991 (1)| 00:
    18:36 | KEY | KEY |
    |* 2 | TABLE ACCESS FULL | rece | 170K| 16M| 92991 (1)| 00:
    18:36 | KEY | KEY |
    --------------------------------------------------------------------------------
    -----------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    2 - filter("DEVICE_NUMBER"='900000015')
    统计信息
    ----------------------------------------------------------
    1 recursive calls
    0 db block gets
    350177 consistent gets
    340572 physical reads
    0 redo size
    9840643 bytes sent via SQL*Net to client
    108067 bytes received via SQL*Net from client
    9779 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    146663 rows processed
    SQL> select * from rece where gpsdate = '20100501' and device_number=
    '900000015' ;
    已选择40396行。
    执行计划
    ----------------------------------------------------------
    Plan hash value: 3235688001
    --------------------------------------------------------------------------------
    ---------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
    | Pstart| Pstop |
    --------------------------------------------------------------------------------
    ---------------------
    | 0 | SELECT STATEMENT | | 50223 | 7651K| 25466 (1)| 00:05
    :06 | | |
    | 1 | PARTITION LIST SINGLE| | 50223 | 7651K| 25466 (1)| 00:05
    :06 | KEY | KEY |
    |* 2 | TABLE ACCESS FULL | rece | 50223 | 7651K| 25466 (1)| 00:05
    :06 | 1 | 1 |
    --------------------------------------------------------------------------------
    ---------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    2 - filter("DEVICE_NUMBER"='900000015')
    统计信息
    ----------------------------------------------------------
    1 recursive calls
    0 db block gets
    96370 consistent gets
    93737 physical reads
    0 redo size
    2713261 bytes sent via SQL*Net to client
    30143 bytes received via SQL*Net from client
    2695 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    40396 rows processed
    SQL>
    SQL> select /*+ index( rece, idx_rece_device_number) */ * from rece where gpsdate >= '20100501' and gpsdate<='20100504' and device_number
    ='900000015' ;
    已选择146663行。
    执行计划
    ----------------------------------------------------------
    Plan hash value: 581505150
    --------------------------------------------------------------------------------
    ----------------------------------------------------
    | Id | Operation | Name | Row
    s | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
    --------------------------------------------------------------------------------
    ----------------------------------------------------
    | 0 | SELECT STATEMENT | | 1
    70K| 16M| 2884K (1)| 09:36:54 | | |
    | 1 | PARTITION LIST ITERATOR | | 1
    70K| 16M| 2884K (1)| 09:36:54 | KEY | KEY |
    | 2 | TABLE ACCESS BY LOCAL INDEX ROWID| rece | 1
    70K| 16M| 2884K (1)| 09:36:54 | KEY | KEY |
    |* 3 | INDEX RANGE SCAN | IDX_rece_DEVICE_NUMBER | 35
    18K| | 10331 (1)| 00:02:04 | KEY | KEY |
    --------------------------------------------------------------------------------
    ----------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    3 - access("DEVICE_NUMBER"='900000015')
    统计信息
    ----------------------------------------------------------
    1 recursive calls
    0 db block gets
    131673 consistent gets
    101010 physical reads
    0 redo size
    9840684 bytes sent via SQL*Net to client
    108067 bytes received via SQL*Net from client
    9779 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    146663 rows processed
    我的参数是:
    SQL> show parameter optimizer_index_cost_adj
    NAME TYPE VALUE
    ------------------------------------ ----------- ------------------------------
    optimizer_index_cost_adj integer 100
    实在搞不清楚,希望大家指教啊。

    ---------------------------------------------Tip---------------------------------------------------

    你加HINT走索引后逻辑读是131673,而没加HINT全表扫描逻辑读是 96370 ,查询返回的结果是最后的40396 rows processed。前者是获取每行需要131673/40396=3个IO ,后者是平均获取每行需要96370/40396=2个IO ,由此可见开销是索引更大,ORACLE当然不走索引了 。
    返回了4万多条记录这个查询的返回确实非常多!这个TABLE ACCESS BY LOCAL INDEX ROWID的开销是离散读, 2884K (1)| 这个有点大,我觉的有可能是clustering_factor太大了。
    建议你查询一下索引的聚合因子clustering_factor

  • 相关阅读:
    linux read 系统调用剖析
    IO流程及优化
    分布式存储比较
    BTree,B-Tree,B+Tree,B*Tree的数据结构
    Spectrum Scale
    unixbench测试
    网络文件系统与 Linux
    协程的实现
    进程池和线程池
    django-spirt 论坛主题
  • 原文地址:https://www.cnblogs.com/tracy/p/2064070.html
Copyright © 2011-2022 走看看