• 部分索引类型介绍\索引重建否\索引压缩


    2011年3月2日

    索引类型:

    索引键压缩
      通过index_stats视图判断索引是否需要压缩:
      select opt_cmpr_count,opt_cmpr_pctsave from index_stats;
      --opt_cmpr_pctsave表示压缩后可节省的空间
      --opt_cmpr_count表示应该压缩的列数即长度
      压缩语法:
      create index index_name on t1(col1, col2, col3, col4) compress &1;--创建时压缩
      alter index index_name rebuild compress &1;--重建时压缩
      --&1表示压缩的长度
      --备注:index_stats视图只有在对索引进行结构分析后才会有记录,而且只存储最后一次对索引分析结构的信息,且只能在本会话中查询看到

    反向键索引( reverse key index ):
        这也是 B* 树索引,只不过键中的字节会 “ 反转 “ 。利用反向键索引,如果索引中填充的是
    递增的值,索引条目在索引中可以得到更均匀的分布。例如,如果使用一个序列来生成主键,这个序列将生成诸如 987500 、 987501 、
     987502 等值。这些值是顺序的,所以倘若使用一 个传统的 B* 树索引,这些值就可能放在同一个右侧块上,这就加剧了对这一块的竞争。
     利用反向键, Oracl e则会逻辑地对 205789 、 105789 、 005789 等建立索引。 Oracle 将数据放在索引中之前,将先把所存储数据的
     字节反转,这样原来可能在索引中相邻放置的值在字节反转之后就会相距很远。通过反转字节,对索引的插入就会分布到多个块上。
     语法:create index index_name on t1(col1) reverse;

    降序索引
    降序索引是8i里面新出现的一种索引,是B*Tree的另一个衍生物,他的变化就是列在索引中的储存方式从升序变成了降序,在某些场合下
    降序索引将会起作用。如下:
    SQL> set autotrace traceonly explain;
    SQL> select * from sys_log where log_id between 45534536 and 45534845 order by l
    og_date asc,log_id desc;

    执行计划
    ----------------------------------------------------------

    -------------------------------------------------------------------
    | Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)|
    -------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |         |   309 | 24411 |   130   (4)|
    |   1 |  SORT ORDER BY     |         |   309 | 24411 |   130   (4)|
    |   2 |   TABLE ACCESS FULL| SYS_LOG |   309 | 24411 |   129   (4)|
    -------------------------------------------------------------------

    --查看创建降序索引后的区别,少了排序步骤(这是因为创建降序索引时Oracle已把数据都按降序排好了)
    create index inx_syslog on sys_log(log_id desc,log_date asc);
    SQL> exec dbms_stats.gather_index_stats('LTTFM','INX_SYSLOG');

    SQL> select * from sys_log where log_id between 45534536 and 45534845 order by l
    og_id desc,log_date asc;

    执行计划
    ----------------------------------------------------------

    -------------------------------------------------------------------------------
    | Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)|
    -------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |            |   309 | 24411 |     5   (0)|
    |   1 |  TABLE ACCESS BY INDEX ROWID| SYS_LOG    |   309 | 24411 |     5   (0)|
    |   2 |   INDEX RANGE SCAN          | INX_SYSLOG |    41 |       |     2   (0)|
    -------------------------------------------------------------------------------

    位图索引
    在一颗 B* 树中,通常索引条目和行之间存在一种一对一的关系:一个索引条目就指向一行。而对于位图索引,一个索引条目则使用一个
    位图同时指向多行。位图索引适用于高度重复而且通常只读的数据(高度重复是指相对于表中的总行数,数据只有很少的几个不同值)。
    考虑在一 个有 100 万行的表中,每个列只有 3 个可取值: Y 、 N 和 NULL 。举例来说,如果你需要频繁地统计多少行有值Y ,
    这就很适合建立位图索引。不过并不是说如果这个表中某一列有 11.000 个不同的值就不能建立位图索引,这一列当然也可以建立
    位图索引。在一个 OLTP 数据库中,由于存在并发性相关的问题,所以不能考虑使用位图索引(后面我们就会讨论这一点)。
    --注意,位图索引要求使用 Oracle 企业版或个人版。
    create bitmap index indexname on t(col1);

    位图联结索引
    create bitmap index emp_bm_idx on emp( d.dname ) from emp e, dept d where e.deptno = d.deptno
    使其他的表的列建立一个索引。在emp上建立一个dept.dname的索引。
    使类似的查询可以只读取索引而不做全表扫描。
    位图联结索引有一个先决条件。联结条件必须联结到另一个表中的主键或惟一键。在前面的例子中DEPT.DEPTNO 就是DEPT 表的主键,
    而且这个主键必须合适,否则就会出现一个错误。

    基于函数的索引
    这些就是 B* 树索引或位图索引,它将一个函数计算得到的结果存储在行的列中,而不是存储列数据本身。可以把基于函数的索引看作一个
    虚拟列(或派生列)上的索引,换句话说,这个列并不物理存储在表中。基于函数的索引可以用于加快形如:
    SELECT * FROM T WHERE FUNCTION(DATABASE_COLUMN) = SAME_VALUE 这样的查询,因为值 FUNCTION(DATABASE_COLUMN) 已经提前
    计算并存储在索引中。

    --无索引的情况下查询
    SQL> select * from i_exch_info where lower(code) ='nh10237';

    执行计划
    ----------------------------------------------------------------------
    | Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)|
    ----------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |             |   171 | 46512 |   171   (3)|
    |   1 |  TABLE ACCESS FULL| I_EXCH_INFO |   171 | 46512 |   171   (3)|
    ----------------------------------------------------------------------
    --创建基于函数的索引后的查询
    create index i_exch_info_lower on i_exch_info(lower(code));
    SQL> select * from i_exch_info where lower(code) ='nh10237';

    执行计划
    | Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)|

    --------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                   |   171 | 46512 |    66(0)|

    |   1 |  TABLE ACCESS BY INDEX ROWID| I_EXCH_INFO       |   171 | 46512 |    66(0)|

    |   2 |   INDEX RANGE SCAN          | I_EXCH_INFO_LOWER |    68 |       |     1(0)|


    对部分行建立索引
    create index idx_exch_info on i_exch_info(case  when g3e_id<50000237 then g3e_id end);

    select * from i_exch_info where g3e_id=50000006;--始终没有使用索引
    select /*+index(t,idx_exch_info)*/* from i_exch_info t where g3e_id=50000006;
    analyze index idx_exch_info validate structure;
    --查看索引
    select * from user_ind_expressions


    判断索引是否需要重建

     途径:通过index_stats视图:index_stats视图只存储最后一次对索引分析结构的信息;
                        而且只能在执行 analyze index index_name validate structure 语句的session会话中看到数值,另外的会话是看不到的.

     对一个索引进行结构分析后,如果该索引占用超过了一个数据块,且满足以下条件之一:B-tree树的高度大于3;使用百分比低于75%;数据删除率大于15%,就需要考虑对索引重建。
      analyze index IDX_P_TILE_STREETAREA_ROWCOL validate structure;--分析索引结构
      --查看该索引的相关信息
      select btree_space, -- if > 8192(块的大小)
            height, -- if > 3
            pct_used, -- if < 75
            del_lf_rows / (decode(lf_rows, 0, 1, lf_rows)) * 100 as deleted_pct -- if > 20%
       from index_stats;
       如果超出了if 后面的值即可能需要进行 index rebuild.


     
  • 相关阅读:
    SAP B1的几点不足
    对公司内审员培训的总结
    我们为了什么而活
    ERP实施一周总结
    SAP B1中物料主数据的术语解释
    好像回到了以前
    ERP总结
    WinHex
    Delphi和Windows主题相关的报错
    事件
  • 原文地址:https://www.cnblogs.com/lanzi/p/1969058.html
Copyright © 2020-2023  润新知