BITMAP CONVERSION FROM ROWIDS/_b_tree_bitmap_plans

本文解析了 Oracle 数据库中 BITMAPCONVERSIONFROMROWIDS 的应用场景与原理,介绍了如何通过建立组合索引或使用 SQL 提示来解决因不适当索引导致的成本较高的执行计划问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BITMAP CONVERSION FROM ROWIDS

第一次写博客,虽然是转载,但也希望能坚持。
在有些执行计划中,可以会看到 BITMAP CONVERSION FROM ROWIDS这样的东东,也许你会感觉奇怪,我没有使用位图索引怎么出现了bitmap。

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系统中,一般都需要解决。
本例的解决办法有两种:
1、删除唯一度低的index,建立组合index。分别删除COMPANY_ID与USER_ID上的index,建立COMPANY_ID和USER_ID的组合index。
2、该hint提示也可以解决该问题:
/*+ opt_param(‘_b_tree_bitmap_plans’, ‘false’) */
OPT_PARAM可以让你在SQL级别通过加HINT的方式来调整单个SQL执行的时候所依赖的系统参数的值。

转自:http://www.xifenfei.com/2011/09/bitmap-conversion-from-rowids.html

另:
这和隐含参数"_b_tree_bitmap_plans"有关,11G默认是true,同时在where条件中出现两条以上的选择条件,而且都有索引,就有可能出现BITMAP CONVERSION FROM ROWIDS。
我在自己做试验时发现如果不走 BITMAP CONVERSION FROM ROWIDS,有时反而cost会比较高,所以出现这种情况不一定必须要优化。存在即合理吧。如果SQL慢,且执行计划有BITMAP CONVERSION FROM ROWIDS,可以用上面的方法试试。

查询隐含参数的语句

SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
FROM SYS.x$ksppi x, SYS.x$ksppcv y
WHERE x.inst_id = USERENV ('Instance')
AND y.inst_id = USERENV ('Instance')
AND x.indx = y.indx
AND x.ksppinm LIKE '%&par%';
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值