--- 说明:案例来自《 收获,不止SQL 优化
请问:Oracle 可以针对某列的部分数据创建索引吗?比如 t1 表 id 列的数据有 1,2,3,4,5 。可以只针对 id=3 的数据创建索引吗?
可以通过函数索引实现只针对id=3 的数据创建索引,例如 :
Create index i_t1_id on t(case when id=3 then 3 end);
请问:请举一个具体案例,并说明在该场景下使用部分索引性能更好?
案例如下:
---创建测试表t
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 <= 100000 ;
SQL > insert into t select 1 , 'N' from dual ;
SQL > commit ;
---数据分布
SQL > select count (*), status from t group by status ;

--- 收集统计信息
SQL > analyze table t compute statistics for table for all indexes for all indexed columns ;
--- 查询表 t ,查看执行计划
SQL > set linesize 1000
SQL > set autotrace traceonly
SQL > select * from t where status = 'N' ;

-- 看索引 信息
SQL > set autotrace off
SQL > analyze index id_normal validate structure ;
SQL > select name , btree_space , lf_rows , height from index_stats ;

备注 INDEX_STATS 存储的是最近一次 ANALYZE INDEX ... VALIDATE STRUCTURE 语句的结果,最多只有 当前会话的 一条数据 。
--- 创建函数索引的情况
SQL > drop index id_normal ;
SQL > create index id_status on t ( Case when status = 'N' then 'N' end );
SQL > analyze table t compute statistics for table for all indexes for all indexed columns ;
--- 再次查看执行计划
SQL > set autotrace traceonly
SQL > select * from t where ( case when status = 'N' then 'N' end )= 'N' ;

--观察id_status索引的情况
SQL > set autotrace off
SQL > analyze index id_status validate structure ;
SQL > select name , btree_space , lf_rows , height from index_stats ;

--- 在对比下之前普通索引的值

结论: 普通索引改成函数索引后,索引当前分配的空间 (BTREE_SPACE) 由 20230168 降到 7996 , , 逻辑读consistent gets 由 5 降到 2 ,索引叶子数 (LF_ROWS) 由 100001 降到 1 ,索引高度 (HEIGHT) 由 3 降到 1 ,性能有所提升。

转载自chenoracle

最后修改:2022 年 02 月 27 日
如果觉得我的文章对你有用,请随意赞赏