Oracle的选择函数索引实验
选择函数索引在某些场合的使用,可以大大减少索引存储空间,并且一定程度提高查询速度.
特别适合于这种情况:
列的值呈现明显的典型特征,并且查询时,主要针对某一个典型值返回结果.
例如:病人挂号记录的执行状态为2表示正在就诊的挂号病人.
由于就诊完成后,执行状态更新为1,所以大多数情况下,该字段的值是1-待诊或2-正在就诊
如果用选择函数(Case语句或Decode)对执行状态建立索引的话,就可以只对记录状态为2或1的建立索引,
这样索引就非常小,并且索引范围扫描时,范围大大减小,查询速度更快.
以下是一个对比试验,通过试验得出如下比较结果:
比项项目 B*树索引 选择函数索引
空间占用 1.8M 0.5M
查询速度 0.06 0.02
(查询返回1312条记录)
由于函数索引有一些要求条件(例如:要求cbo,要授权等),所以,不能轻易大范围的使用.
------------------------------------------------------------------------------------------------------------
--B*树索引
SQL> alter system set QUERY_REWRITE_ENABLED=TRUE;
System altered
SQL> grant query rewrite to zlhis;
Grant succeeded
SQL> drop index 病人挂号记录_IX_执行状态;
Index dropped
SQL> CREATE INDEX 病人挂号记录_IX_执行状态 ON 病人挂号记录(执行状态) PCTFREE 10 TABLESPACE zl9Patient;
Index created
SQL> analyze table 病人挂号记录 compute statistics
2 for table
3 for all indexes
4 for all indexed columns;
SQL> exec show_space('病人挂号记录_IX_执行状态','ZLHIS','INDEX');
Free Blocks.............................0
Total Blocks............................225
Total Bytes.............................1843200
Unused Blocks...........................17
Unused Bytes............................139264
Last Used Ext FileId....................11
Last Used Ext BlockId...................4297
Last Used Block.........................3
PL/SQL procedure successfully completed
SQL> Select 门诊号,姓名 From 病人挂号记录 Where 执行状态=2;
已选择1312行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=19 Card=1312 Bytes=35424)
1 0 TABLE ACCESS (BY INDEX ROWID) OF '病人挂号记录' (Cost=19 Card=1312 Bytes=35424)
2 1 INDEX (RANGE SCAN) OF '病人挂号记录_IX_执行状态' (NON-UNIQUE) (Cost=3 Card=1312)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
196 consistent gets
0 physical reads
0 redo size
42326 bytes sent via SQL*Net to client
10082 bytes received via SQL*Net from client
89 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1312 rows processed
-----------------------------------------------------------
Select 门诊号,姓名
From
病人挂号记录 Where 执行状态=2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.02 0.02 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 89 0.02 0.04 0 196 0 1312
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 91 0.04 0.06 0 196 0 1312
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 141
Rows Row Source Operation
------- ---------------------------------------------------
1312 TABLE ACCESS BY INDEX ROWID 病人挂号记录
1313 INDEX RANGE SCAN (object id 53400)
------------------------------------------------------------------------------------------------------------
--选择函数索引
------------------------------------------------------------------------------------------------------------
SQL> drop index 病人挂号记录_IX_执行状态;
Index dropped
SQL> CREATE INDEX 病人挂号记录_IX_执行状态 ON 病人挂号记录(decode(执行状态,2,2,Null)) PCTFREE 10 TABLESPACE zl9Patient;
Index created
SQL> analyze table 病人挂号记录 compute statistics
2 for table
3 for all indexes
4 for all indexed columns;
SQL> exec show_space('病人挂号记录_IX_执行状态','ZLHIS','INDEX');
Free Blocks.............................0
Total Blocks............................65
Total Bytes.............................532480
Unused Blocks...........................60
Unused Bytes............................491520
Last Used Ext FileId....................11
Last Used Ext BlockId...................4092
Last Used Block.........................5
PL/SQL procedure successfully completed
SQL> Select 门诊号,姓名 From 病人挂号记录 Where decode(执行状态,2,2,Null)=2;
已选择1312行。
---------------------------------------------------
注意:查询条件,必须和索引建立时的条件完全匹配,否则用不到索引,decode(执行状态,2,2,Null)
---------------------------------------------------
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1312 Bytes=35424)
1 0 TABLE ACCESS (BY INDEX ROWID) OF '病人挂号记录' (Cost=2 Card=1312 Bytes=35424)
2 1 INDEX (RANGE SCAN) OF '病人挂号记录_IX_执行状态' (NON-UNIQUE) (Cost=1 Card=1312)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
196 consistent gets
0 physical reads
0 redo size
42326 bytes sent via SQL*Net to client
10082 bytes received via SQL*Net from client
89 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1312 rows processed
----------------------------------------------------------
Select 门诊号,姓名
From
病人挂号记录 Where decode(执行状态,2,2,Null)=2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 89 0.02 0.02 0 196 0 1312
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 91 0.02 0.02 0 196 0 1312
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 141
Rows Row Source Operation
------- ---------------------------------------------------
1312 TABLE ACCESS BY INDEX ROWID 病人挂号记录
1313 INDEX RANGE SCAN (object id 53399)
![](http://pic.cnblogs.com/avatar/3632/20170709231802.png)
posted on 2006-04-02 02:23 知道得越多知道的越少 阅读(894) 评论(0) 编辑 收藏 举报