_b_tree_bitmap_plans的一次使用

备注:因为实在无法在自己电脑上还原出此类情况,以下例子使用了工作时的截图

前几天上班的时候,同事遇到一个问题,cpu cost会少的一句sql,竟然返回很慢。

两列都有独自的普通索引,但是在执行计划里多出了个BITMAP CONVERSION FROM ROWIDS的过程。

参考了惜分飞的博客后,他的解释如下:

其目的是:.oracle将btree索引中获得的rowid信息通过BITMAP CONVERSION FROM ROWIDS的步骤转换成bitmap进行匹配,然后匹配完成后通过BITMAP CONVERSION TO ROWIDS再转换出rowid获得数据或者回表获得数据。

这种想象出现的原因为:oracle的cbo是根据cost来决定大小来选择合适的执行计划,当它计算获得通过bitmap的方式执行的时候cost会更小,它就会选择使用这样的执行计划。

一般出现这样的情况,都是因为对表建立的不适当的index导致,特别是对表中的唯一度不高的列建立了index,然后oracle就有可能选择两个这样的列转为为bitmap来执行。根据oracle的执行计划,肯定是cost最小的,但是它很多时候忽略了一致性读等其他条件,导致这个执行计划并非像oracle想象的那样最优,因为把btree index转为为bitmap index执行,需要消耗更多的cpu,特别是在cpu比较紧张的系统中,所以这样的情况如果发生在oltp系统中,一般都需要解决。
本例的解决办法是删除唯一度低的index,建立组合index

以上用了他文章中的原话,不过在本例中启用了老外的建议,将参数 _b_tree_bitmap_plans设置为了false

alter session "_b_tree_bitmap_plans"=false;

可以看到当该参数设置为false后,不会出现将索引转换成位图的情况了。

不过可以发现,转换成位图索引的情况下cpu的消耗并不高,所以我对以上蓝色下划线字体的论述产生了质疑。

借鉴itpub上的一篇帖子,了解到当转换成位图索引时,cpu消耗会减低,但是会造成大量物理读(因为要将所有的索引读出,形成位图)。但是不转换时相反,cpu消耗会增高,物理读数量不高。

这又是一个典型的io和cpu之间的博弈了。本例中,cpu资源相对充裕,而io资源相对紧张,查询优化器使用了一个cost最小的执行计划,导致了比原来更慢。

本例中修改了隐藏参数解决问题,但是实际情况下,并不建议修改隐藏参数,这个会对系统造成隐患。比较好的解决方案是对于组合索引进行测试,在决定接下去的方式。

以下是隐藏参数 _b_tree_bitmap_plans的解释:使用B树索引的位图计划(该核心思想是数据库引擎能基于B树索引扫描返回的结果构建存在内存中的位图索引)

参考资料:

http://www.xifenfei.com/1531.html

http://www.itpub.net/thread-1068796-1-1.html

http://orafaq.com/parms/index.htm

原文地址:https://www.cnblogs.com/archersun/p/3173141.html