索引瘦身_oracle_11g

假设一个表,10个列,字段列长度分布均匀。

一个表10G,那么一个列的索引+rowid,肯定是在1G+

例如有个场景:一个客户数据库,一个业务表,记录STATUS状态列,欠费A,正常B。

如果没到月底,只统计欠费的少量数据,如何创建相匹配的索引。

如果一个表有1个亿,欠费数量只有500时! 如果常规创建索引SQL>create index cc_status on A(status);  索引将非常大!

此事,可以使用如下测试方式,进行索引瘦身:

1.优点,索引变小;

2.缺点:或者说使用索引的SQL需要改写或者与该函数索引相匹配。

一、测试用法

SQL> conn tt/tt
Connected.
SQL> create table b as select * from dba_objects;
SQL> select count(*) from b where status='INACTIVE';
  COUNT(*)
----------
         0
SQL> update b set status='INACTIVE' where rownum=1;
update b set status='INACTIVE' where rownum=1
                    *
ERROR at line 1:
ORA-12899: value too large for column "TT"."B"."STATUS" (actual: 8, maximum: 7)
SQL> alter table b modify STATUS varchar2(10);
Table altered.
SQL>  update b set status='INACTIVE' where rownum=1;
1 row updated.
SQL> commit;
Commit complete.
SQL> create index cc_ind_status on b(case when STATUS='INACTIVE' then 1 else null end);
Index created.
SQL> select count(*) from b where STATUS='INACTIVE';
  COUNT(*)
----------
         1
Execution Plan
----------------------------------------------------------
Plan hash value: 749587668

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     7 |   345   (1)| 00:00:05 |
|   1 |  SORT AGGREGATE    |      |     1 |     7 |            |          |
|*  2 |   TABLE ACCESS FULL| B    |    14 |    98 |   345   (1)| 00:00:05 |
---------------------------------------------------------------------------
select count(*) from b where (case when STATUS='INACTIVE' then 1 else null end)=1;
SQL> select count(*) from b where (case when STATUS='INACTIVE' then 1 else null end)=1
  COUNT(*)
----------
         1
Execution Plan
----------------------------------------------------------
Plan hash value: 1978997881
-----------------------------------------------------------------------------------
| Id  | Operation         | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |               |     1 |     3 |     1   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE   |               |     1 |     3 |            |          |
|*  2 |   INDEX RANGE SCAN| CC_IND_STATUS |     1 |     3 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(CASE "STATUS" WHEN 'INACTIVE' THEN 1 ELSE NULL END =1)
Note
-----
   - dynamic sampling used for this statement (level=2)

二、对比大小

SQL> create index cc_ind_status_2 on b(status);

SQL>select SEGMENT_NAME,BYTES/1024/1024 from user_segments where SEGMENT_NAME like 'CC_IND_STA%';

SEGMENT_NAME BYTES/1024/1024
-------------------- ---------------
CC_IND_STATUS       .0625
CC_IND_STATUS_2        2

SQL> analyze table b compute statistics;  

SQL> select INDEX_NAME,NUM_ROWS from user_indexes where INDEX_NAME like 'CC_IND_STA%';

INDEX_NAME NUM_ROWS
------------------------------------------------------------ ----------
CC_IND_STATUS 1
CC_IND_STATUS_2 86341

 

你可能感兴趣的:(索引瘦身_oracle_11g)