zoukankan      html  css  js  c++  java
  • (转)分析索引快速获取索引信息

    索引的健康状态是我们非常关注的一个问题。健康的索引可以在保证有效使用空间的基础上,提供很好的搜索性能。同样,一些非健康的索引也会一定程度上影响系统运行的效率。

    在一些数据DML操作频繁的系统中,索引是联动进行更新,不断组建成新的索引树,与数据列相匹配。但是因为各种原因,索引的结构通常都是在不断退化的趋势上。比如:

    使用堆表结构的时候,数据行是随机进行插入操作,这样引起数据表相同值离散程度高。这样,索引的聚集因子clustering_factor就是显著提高。这样的索引,在使用的时候是有一些性能问题的。(详细阐述参见:http://space.itpub.net/17203031/viewspace-680936);

    索引从逻辑结构上是一个B*树的结构,由分支节点和叶子节点构成。索引路径所提供的快速搜索,就是根据索引列键值大小,直接从根节点经过几个分支节点后,快速定位到键值所在数据行的物理地址rowid。在DML频繁的数据表中,B*树的结构是不断的进行组合和演化,当高度和分支节点很高时,会影响性能。

    此外,Oracle的索引树是不能进行节点删除的。对应rowid的键值分布在叶子节点上,一旦对应的数据行删除,叶子节点是不会被从树上被删去,而是被标记为删除。这样,随着DML操作的继续,索引树是一个不断膨胀的物理结构。在空占有很大存储空间的同时,一颗较大的B*树进行搜索的效率也是不高的。

    那么,维护一个健康的索引,是DBA应该关注的问题。那么,接下来就是两个问题。首先,我们如何知道某个索引已经结构恶化?其次,恶化后的索引如何处理?也就是本篇要介绍的方法。

    分析索引健康程度

    Oracle中,提供了索引分析语句analyze index,用来分析指定的索引信息。分析后的结果可以在视图index_stats中查看到。

    首先,我们进行数据准备。

    SQL> create table t as select * from dba_objects;

    Table created

    //构建索引结构

    SQL> create index idx_t_id on t(object_id);

    Index created

    SQL> select count(*) from t;

     COUNT(*)

    ----------

        53338

    SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);

    PL/SQL procedure successfully completed

    //为模拟DML操作频繁,进行一些DML操作

    SQL> delete t where wner='SCOTT';

    24 rows deleted

    SQL> delete t where wner='SYSTEM';

    454 rows deleted

    SQL> delete t where mod(object_id,7)=0;

    7554 rows deleted

    SQL> delete t where length(object_name)=10;

    562 rows deleted

    SQL> insert into t select * from dba_objects where object_id>40000;

    13787 rows inserted

    SQL> commit;

    Commit complete

    //将数据维持在5万多条;

    SQL> select count(*) from t;

     COUNT(*)

    ----------

        58531

    首先,进行索引分析。

    SQL> analyze index idx_t_id validate structure;

    Index analyzed

    SQL> desc index_stats;

    Name                Type        Nullable Default Comments            

    -------------------- ------------ -------- ------- -----------------------------------------------------------------------

    HEIGHT              NUMBER      Y               height of the b-tree     

    BLOCKS              NUMBER      Y               blocks allocated to the segment

    NAME                VARCHAR2(30) Y               name of the index 

    PARTITION_NAME      VARCHAR2(30) Y      name of the index partition, if partitioned

    LF_ROWS             NUMBER      Y       number of leaf rows (values in the index)

    LF_BLKS             NUMBER      Y               number of leaf blocks in the b-tree

    LF_ROWS_LEN         NUMBER      Y             sum of the lengths of all the leaf rows  

    LF_BLK_LEN          NUMBER      Y               useable space in a leaf block           

    BR_ROWS             NUMBER      Y               number of branch rows     

    BR_BLKS             NUMBER      Y               number of branch blocks in the b-tree  

    BR_ROWS_LEN         NUMBER   Y  sum of the lengths of all the branch blocks in the b-tree  

    BR_BLK_LEN          NUMBER      Y               useable space in a branch block       

    DEL_LF_ROWS         NUMBER      Y           number of deleted leaf rows in the index    

    DEL_LF_ROWS_LEN     NUMBER      Y        total length of all deleted rows in the index 

    DISTINCT_KEYS       NUMBER      Y               number of distinct keys in the index          

    MOST_REPEATED_KEY   NUMBER Y    how many times the most repeated key is repeated

    BTREE_SPACE         NUMBER      Y  total space currently allocated in the b-tree 

    USED_SPACE          NUMBER      Y   total space that is currently being used in the b-tree     

    PCT_USED            NUMBER      Y               percent of space allocated in the b-tree that is being used                                                                                         

    ROWS_PER_KEY        NUMBER      Y               average number of rows per distinct key                                                                                                             

    BLKS_GETS_PER_ACCESS NUMBER      Y               Expected number of consistent mode block gets per row. This assumes that a row chosen at random from the table is being searched for using the index

    PRE_ROWS            NUMBER      Y               number of prefix rows (values in the index)                                                                                                         

    PRE_ROWS_LEN        NUMBER      Y               sum of lengths of all prefix rows                                                                                                                   

    OPT_CMPR_COUNT      NUMBER      Y               optimal prefix compression count for the index                                                                                                      

    OPT_CMPR_PCTSAVE    NUMBER      Y               percentage storage saving expected from optimal prefix compression                                                                   

    使用analyze进行分析后,就可以查看index_stats视图。我们查看该视图的描述信息,其中包括了对索引树的分支和叶子节点数据块、对应行数和长度等详细信息。其中篇幅原因,我们关注如下查询结果。

    SQL> col name for a15;

    SQL> select name, height, blocks, lf_rows, lf_blks, br_rows, br_blks, del_lf_rows, btree_space, used_space from index_stats;

    NAME               HEIGHT    BLOCKS   LF_ROWS   LF_BLKS   BR_ROWS   BR_BLKS DEL_LF_ROWS BTREE_SPACE USED_SPACE

    --------------- ---------- ---------- ---------- ---------- ---------- ---------- ----------- ----------- ----------

    IDX_T_ID                2       256     64846       175       174         1       6316    1408032   1029261

    可以清楚看出,索引idx_t_id对应的树高度为2,共占用了256个数据块。对应死叶节点为6316个,总叶行为64846个,比例近似为10%。请注意:当前记录为5万多个,多余的基本上都是被删除的叶节点记录。

    通常,我们判断是否索引健康,可以关注高度和死叶节点比例。如果过高的树高度或者死节点比例过高,就可能要考虑进行索引重建。

    索引处理

    对不适合的索引,我们能进行的操作只有是将索引重建rebuild。删除原有结构,重建结构。

    SQL> alter index idx_t_id rebuild;

    Index altered

     

    SQL> analyze index idx_t_id validate structure;

     

    Index analyzed

     

    SQL> select name, height, blocks, lf_rows, lf_blks, br_rows, br_blks, del_lf_rows, btree_space, used_space from index_stats;

     

    NAME               HEIGHT    BLOCKS   LF_ROWS   LF_BLKS   BR_ROWS   BR_BLKS DEL_LF_ROWS BTREE_SPACE USED_SPACE

    --------------- ---------- ---------- ---------- ---------- ---------- ---------- ----------- ----------- ----------

    IDX_T_ID                2       256     58530       130       129         1          0    1048032    929877

    观察可见,叶子节点个数已经与数据行数相匹配(58530),死节点个数为0

    注意:索引的重建与否、重建方式是一个需要仔细分析和研究的问题。索引随着数据的不断加入、删除而不断成长,定期进行维护是理所当然的事情。但是一些特殊的情况下(一些文献资料中),的确存在旧索引结构更加适合应用需求的时候。同时,rebuild一个非常大的数据表索引,会将数据表锁住一段时间。在生产环境下,需要格外注意rebuild操作对生产环境的影响。在Oracle11g中,完善了online维护索引的功能,这些都给rebuild索引提供了一些便利。

    摘自:http://space.itpub.net/?uid-17203031-action-viewspace-itemid-689810

  • 相关阅读:
    CSS印象不深的小地方
    gulp常用插件的使用
    移动端手势库Hammer.js—增强touch事件或手势
    HTML5拖放与文件操作api,实现拖拽上传文件功能
    Less相关
    gulp使用(一)
    将博客搬至CSDN
    jquery Ajax 通过jsonp的方式跨域提交表单
    解决“The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path”问题
    使用eclipse4.5创建maven项目
  • 原文地址:https://www.cnblogs.com/newmanzhang/p/3281595.html
Copyright © 2011-2022 走看看