函數索引使用之部分記錄建索引

以前沒有接觸到,的確是sql優化很經典的方法

假設有這樣一個情況,在一個表中的某一個字段的某一個值相對於其他值經常使用,但是表的記錄比較大,我們就可以使用這種方法
具體的實例如下:

SQL> drop table t purge;
表已刪除。
SQL> set autotrace off
SQL> create table t (id int ,status varchar2(2));
表已創建。

--建立普通索引
SQL> create index id_normal on t(status);
索引已創建。
SQL> insert into t select rownum ,'Y' from dual connect by rownum<=1000000;
已創建1000000行。
SQL> insert into t select 1 ,'N' from dual;
已創建 1 行。
SQL> commit;
--進行表分析
SQL> analyze table t compute statistics for table for all indexes for all indexe d columns;

--當使用普通索引性能如下
SQL> set linesize 1000
SQL> set autotrace traceonly
SQL> select * from t where status='N';
SQL> select * from t where status='N';
執行計劃
----------------------------------------------------------
Plan hash value: 2252729315
-------------------------------------------------------------------------------- --------- 
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| T ime | 
-------------------------------------------------------------------------------- --------- 
| 0  | SELECT STATEMENT |      | 1     | 10 | 4 (0)| 0 0:13:35 | 
| 1  | TABLE ACCESS BY INDEX ROWID| T  | 1 | 10 | 4 (0)| 0 0:13:35 | 
|* 2 | INDEX RANGE SCAN | ID_NORMAL | 1 | | 3 (0)| 0 0:10:11 | 
-------------------------------------------------------------------------------- --------- 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("STATUS"='N')
統計信息
----------------------------------------------------------
          1 recursive calls
          0 db block gets
          5 consistent gets --產生5個邏輯讀
          0 physical reads
          0 redo size
        595 bytes sent via SQL*Net to client
        519 bytes received via SQL*Net from client
          2 SQL*Net roundtrips to/from client
          0 sorts (memory)
          0 sorts (disk)
          1 rows processed

--查看索引的詳細信息
SQL> set autotrace off
SQL> analyze index id_normal validate structure;
索引已分析
SQL> select name,btree_space,lf_rows,height from index_stats;
NAME BTREE_SPACE LF_ROWS HEIGHT
------------------------------ ----------- ---------- ----------
ID_NORMAL 22600352 1000001 3
SQL> set autotrace off
SQL> analyze index id_normal validate structure;
索引已分析
SQL> select name,btree_space,lf_rows,height from index_stats;
NAME                           BTREE_SPACE  LF_ROWS    HEIGHT
------------------------------ ----------- ---------- ----------
ID_NORMAL                        22600352   1000001      3   --產生的索引的詳細信息

--建函數索引
SQL> drop index id_normal; 
索引已刪除。
SQL> create index id_status on t (Case when status= 'N' then 'N' end);
/*
   select * from t where (case when status='N' then 'N' end)='N' 
   可以使用這種寫法代替上面的寫法

*/
索引已創建。
SQL> analyze table t compute statistics for table for all indexes for all indexe d columns;


--查看函數索引的性能

SQL> set autotrace traceonly
SQL> select * from t where (case when status='N' then 'N' end)='N';
執行計劃
----------------------------------------------------------
Plan hash value: 1835552001
-------------------------------------------------------------------------------- --------- 
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| T ime | 
-------------------------------------------------------------------------------- --------- 
| 0 | SELECT STATEMENT | | 1 | 10 | 2 (0)| 0 0:06:48 | 
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 10 | 2 (0)| 0 0:06:48 | 
|* 2 | INDEX RANGE SCAN | ID_STATUS | 1 | | 1 (0)| 0 0:03:24 | 
-------------------------------------------------------------------------------- --------- 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(CASE "STATUS" WHEN 'N' THEN 'N' END ='N')
統計信息
----------------------------------------------------------
         15 recursive calls
          0 db block gets
          2 consistent gets
          0 physical reads
          0 redo size
        591 bytes sent via SQL*Net to client
        519 bytes received via SQL*Net from client
          2 SQL*Net roundtrips to/from client
          0 sorts (memory)
          0 sorts (disk)
          1 rows processed

--接着觀察函數索引的情況
SQL> set autotrace off
SQL> analyze index id_status validate structure;
索引已分析
SQL> select name,btree_space,lf_rows,height from index_stats;
NAME                           BTREE_SPACE   LF_ROWS  HEIGHT
------------------------------ ----------- ---------- ----------
ID_STATUS                       8000         1             1  --函數索引的要少很多

使用函數索引減少了邏輯讀,一定程度提高了sql的性能。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章