zoukankan      html  css  js  c++  java
  • Oracle之虚拟索引

    一、引言

        DBA在日常维护管理数据库进行低性能SQL分析时,有时候需要通过创建索引对SQL进行优化,但有些时候我们创建的索引是否能用到?这个只能创建以后才能看出效果,但是在实际工作中,特别是对大表创建索引对系统性能有很大影响,因此我们不得不避开业务高峰时段,但是有没有一种办法创建索引而不影响性能呢?有,那就是虚拟索引。

        虚拟索引不是物理存在的,它并不会创建实际的索引段,只是在数据字典中加了一个索引的记录,使得优化器能够意识到一个索引的存在,从而判断是否使用该索引作为访问路径。作用仅仅是为了DBA作SQL优化时使用,DBA根据虚拟索引的优化效果决定是否创建物理索引。

    二、虚拟索引类型

        虚拟索引支持B-TREE索引和BIT位图索引,在CBO模式下ORACLE优化器会考虑虚拟索引,但是在RBO模式下需要添加hint才行。

    三、虚拟索引创建实例

    SQL> drop table t purge;
    表已删除。
    SQL> create table t as select * from dba_objects;
    表已创建。
    --创建虚拟索引,首先要将_use_nosegment_indexes的隐含参数设置为true
    SQL> alter session set "_use_nosegment_indexes"=true;
    会话已更改。
    --虚拟索引的创建语法比较简单,实际上就是普通索引语法后面加一个nosegment关键字
    SQL> create index ix_t_id on t(object_id) nosegment;
    索引已创建。
    SQL> explain plan for select * from t where object_id=1;
    已解释。
    SQL> set linesize 1000
    SQL> select * from table(dbms_xplan.display());
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Plan hash value: 206018885
    ---------------------------------------------------------------------------------------
    | Id  | Operation            | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT        |          |    12 |  2484 |     5    (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T       |    12 |  2484 |     5    (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN        | IX_T_ID |   273 |       |     1    (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    
       2 - access("OBJECT_ID"=1)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    已选择18行。
    
    SQL> set autotrace traceonly
    SQL> select * from t where object_id=1;
    
    未选定行
    
    执行计划
    ----------------------------------------------------------
    Plan hash value: 206018885
    
    ---------------------------------------------------------------------------------------
    | Id  | Operation            | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT        |          |    12 |  2484 |     5    (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T       |    12 |  2484 |     5    (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN        | IX_T_ID |   273 |       |     1    (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("OBJECT_ID"=1)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    统计信息
    ----------------------------------------------------------
          4  recursive calls
          0  db block gets
           1101  consistent gets
        753  physical reads
          0  redo size
           1184  bytes sent via SQL*Net to client
        404  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed
    
    SQL> set autotrace off
    --以下看的是真实执行计划,显然是用不到索引。
    SQL> alter session set statistics_level=all;
    
    会话已更改。
    
    SQL> select * from t where object_id=1;
    
    未选定行
    
    SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID    2qhwh0nzrzx2r, child number 1
    -------------------------------------
    select * from t where object_id=1
    
    Plan hash value: 1601196873
    
    ------------------------------------------------------------------------------------
    | Id  | Operation      | Name | Starts | E-Rows | A-Rows |    A-Time     | Buffers |
    ------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |     |    1 |       |      0 |00:00:00.01 |    1037 |
    |*  1 |  TABLE ACCESS FULL| T     |    1 |    12 |      0 |00:00:00.01 |    1037 |
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("OBJECT_ID"=1)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    已选择22行。
    --从数据字段中是无法找到这个索引的。
    SQL> select index_name,status from user_indexes where table_name='T';
    
    未选定行

    四、虚拟索引的特点
        4.1、虚拟索引无法执行alter index选项

    SQL> alter index IX_T_ID rebuild;
    alter index IX_T_ID rebuild
    *1 行出现错误:
    ORA-08114: 无法变更假索引

        4.2、使用回收站特性的时候,虚拟索引必须显示drop,才能创建同名的索引。

    SQL> create index ind_status on t(status);
    
    索引已创建。
    SQL> drop table t;
    
    表已删除。
    
    SQL> flashback table t to before drop;
    
    闪回完成。
    
    SQL> select table_name,index_name,status from user_indexes where table_name='T';
    
    TABLE_NAME               INDEX_NAME              STATUS
    ------------------------------ ------------------------------ --------
    T                   BIN$7jAFlUG6b1zgQAB/AQAPyw==$0 VALID
    
    SQL> create index ind_object_id on t(object_id);
    
    索引已创建。
    
    SQL> create index inds_status on t(status);
    create index inds_status on t(status)
                                  *1 行出现错误:
    ORA-01408: 此列列表已索引

        4.3、不能创建和虚拟索引同名的实际索引;
        4.4、可以创建和虚拟索引包含相同列但不同名的实际索引;

        4.5、虚拟索引分析并且有效,但是数据字典里查不到结果。

  • 相关阅读:
    类型:NodeJs;问题:默认IE的编码为utf8;结果:IE不能自动选择UTF-8编码解决办法
    类型:Java;问题:eclipse配置maven;结果:eclipse配置maven
    类型:Oracle;问题:oracle 时间加减;结果:ORACLE 日期加减操作
    类型:Ajax;问题:ajax调用ashx参数获取不到;结果:ashx文件获取$.ajax()方法发送的数据
    类型:JQuery;问题:ajax调用ashx文件;结果:ashx文件怎么获取$.ajax()方法发送的json数据
    类型:Jquery;问题:jquery调用后台带参数方法;结果:利用JQuery的$.ajax()可以很方便的调用asp.net的后台方法。
    问题:asp.net 点击button按钮调到页面顶部;结果:asp.net点击一个按钮,使页面跳转到本面页上的指定位置
    问题:ClientIDMode属性;结果:ASP.NET 4.0的ClientIDMode属性
    金木水火土五行查询表
    并发编程的基础
  • 原文地址:https://www.cnblogs.com/Richardzhu/p/3487594.html
Copyright © 2011-2022 走看看