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.


 

 

posted on 2011-03-02 16:37  蓝紫  阅读(962)  评论(0编辑  收藏  举报