第一章 Oracle索引位图转换介绍
1.1 索引位图转换
首先介绍一下索引位图转换概念:
索引位图转换是优化器对目标表上的一个或多个目标索引执行位图布尔运算。Oracle数据库里有一个映射函数(Mapping Function),它可以实现B树索引中ROWID和对应位图索引中的位图之间互相转换。目的是对相同ROWID做AND、OR等连接运算。
当执行计划中出现“BITMAP CONVERSION FROM/TO ROWIDS”、“BITMAP AND”,说明Oracle对应的索引将其中的ROWID转换成了位图,然后对转换后的位图执行了BITMAP AND(位图按位与)布尔运算。最后将布尔运算的结果再次用映射函数转换成了ROWID并回表得到最终的结果。
1.2 性能分析
根据我们以往的经验,用映射函数将ROWID转换成位图,这期间可能访问了多个索引,甚至一个索引会访问N多次。然后在执行位图布尔运算。最后再将运算结果转换为ROWID并回表,这个过程在实际生产环境中的执行效率往往是有问题的,我们可以通过隐藏参数_b_tree_bitmap_plans禁掉该过程中从ROWID到位图的转换。
但实际上当我们看到“BITMAP CONVERSION FROM/TO ROWIDS”的执行计划,一定代表着存在性能问题吗?
下面我用一个案例来说明:
创建测试表结构如下:
DROP TABLE T1 PURGE;
CREATE TABLE T1 AS SELECT * FROM DBA_OBJECTS;
CREATE INDEX IDX_T1_ID ON T1(OBJECT_ID);
EXEC dbms_stats.gather_table_stats(ownname=>'SZT',tabname =>'T1');
- 1.
- 2.
- 3.
- 4.
第二章 实验环境测试
实验脚本如下:
select * from (
select * from t1 WHERE object_id>88500 or object_id in (1,2,3,4,5,6,7)
order by object_id)
where rownum88500 or object_id in (1,2,3,4,5,6,7)
order by object_id)
where rownum88500 or object_id in (1,2,3,4,5,6,7)
order by object_id)
where rownum'SZT',tabname =>'T2');
- 1.
- 2.
- 3.
- 4.
通过打乱表数据的顺序,降低聚簇因子值。
可以看到聚簇因子几乎接近于表中数据行数,且索引叶子块也有所增加。
2.2.1 比较执行效率
select * from (
select * from t2 WHERE object_id>88500 or object_id in (1,2,3,4,5,6,7)
order by object_id)
where rownum88500 or object_id in (1,2,3,4,5,6,7)
order by object_id)
where rownum88450 or object_id in (1,2,3,4,5,6,7)
order by object_id)
where rownum88450 or object_id in (1,2,3,4,5,6,7)
order by object_id)
where rownum