联系:手机/微信(+86 17813235971) QQ(107644445)
标题:BITMAP CONVERSION FROM ROWIDS
作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]
在有些执行计划中,可以会看到 BITMAP CONVERSION FROM ROWIDS这样的东东,也许你会感觉奇怪,我没有使用位图索引怎么出现了bitmap。
我通过一个sql和大家分析下原因:
sql语句为:
SELECT * FROM (SELECT a.*, ROWNUM rn FROM ( SELECT module_no, MAX (id) AS id FROM vasoa.tab_moa_historypage t WHERE t.company_id = :1 AND t.user_id = :2 AND t.TYPE = :3 GROUP BY module_no ORDER BY id DESC) a WHERE ROWNUM <= :4) b WHERE b.rn >= :5
执行计划为:
表结构为:
目前索引情况:
通过观察执行计划的图片可以发现,使用了 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。分别删除COMPANY_ID与USER_ID上的index,建立COMPANY_ID和USER_ID的组合index,执行计划如下:
该hint提示也可以解决该问题:/*+ opt_param(‘_b_tree_bitmap_plans’, ‘false’) */
OPT_PARAM可以让你在SQL级别通过加HINT的方式来调整单个SQL执行的时候所依赖的系统参数的值
请教一下,既然唯一度低,为什么不直接创建位图索引呢?
位图索引对于oltp系统影响非常大,dml操作将引起大量锁