<div>
<b style="line-height:1.5;">一、bitmap概要</b>
</div>
<div>
纲要内容:<br />
1.定义,什么是位图索引:就是用位图表示的索引,oracle对于选择度底的列的每个键值建立一个位图,位图中的每一位可能对应多个列,位图中位等于1表示特定的行含有此位图表示的键值。<br />
2.查询,由于索引是位图,所以很多很多时候可以对这些索引中的位图进行位运算-(and 和 or),这样的速度明显比b树快(某些情况下)。由于位图索引可以存储null,所以可以直接通过位图索引计数(肯定是准确的)。后面提到的有点和位图的计算方式是直接相关的。<br />
3.位图的优点(主要针对dw):<br />
<ul data-front-font-size="14px" style="margin-top:0px;margin-bottom:0px;font-size:14px;">
<li>
减少即席查询的相应时间
</li>
<li>
和其它类型索引比较,真正节约了索引数据空间
</li>
<li>
即使在非常差的硬件上,也可能会有戏剧化的性能提升
</li>
<li>
高效的并行DML和LOAD操作。
</li>
<li>
生成索引的时候更高效,首先是不排序,其次是占用的空间少(索引空间)。
</li>
<li>
可以通过位图索引直接计数。<br />
</li>
</ul>
<p>
4.位图索引的缺点(其它资料),也不好说是缺点
</p>
<ul data-front-font-size="14px" style="margin-top:0px;margin-bottom:0px;font-size:14px;">
<li>
不适合选择度底的列
</li>
<li>
如果有比较频繁的insert,update等操作,可能导致性能很底下,因为更新索引用的是行锁(可能锁定多行),而不是排它锁。
</li>
<li>
可能会溢出,索引数据块难于放下整个索引值,这导致低效。
</li>
</ul>
<div>
<br />
</div>
<div>
<b style="background-color:inherit;">二、主要了解以下位图原理图</b><br style="font-family:微软雅黑;font-size:14px;background-color:#FFFFFF;" />
<div style="font-family:微软雅黑;font-size:14px;background-color:#FFFFFF;">
<img data-media-type="image" data-attr-org-src-id="8E5B0CED42BD49098911007365EA4D00" data-attr-org-img-file="file:///D:/%E6%9C%89%E9%81%93%E4%BA%91%E7%AC%94%E8%AE%B0/%E6%95%B0%E6%8D%AE%E7%9B%AE%E5%BD%95/zr2095@163.com/9e1562e4eb3f487794640ad476189bf2/65111196479.jpeg" src="file://D:/%E6%9C%89%E9%81%93%E4%BA%91%E7%AC%94%E8%AE%B0/%E6%95%B0%E6%8D%AE%E7%9B%AE%E5%BD%95/zr2095@163.com/9e1562e4eb3f487794640ad476189bf2/65111196479.jpeg" alt="oracle位图索引 - 我行我素 - 逝者如斯夫,不舍昼夜" style="background-color:inherit;cursor:default;display:inline-block;margin-top:8px;max-width:800px;height:auto;" />
</div>
<img src="/attachment/201510/8/30208428_144428958888JP.jpeg" width="492" height="376" alt="" /><br />
<div style="font-family:微软雅黑;font-size:14px;background-color:#FFFFFF;">
<br />
<img src="/attachment/201510/8/30208428_144428960179wx.jpeg" width="679" height="513" alt="" />
</div>
<div style="font-family:微软雅黑;font-size:14px;background-color:#FFFFFF;">
<br style="background-color:inherit;" />
需要注意的是,这只是个示意图,实际上每个位图的位数并非刚好等于记录数,而是会根据情况来分解,否则对于居多的数据而言,位图未免太大了。
</div>
<br />
<br />
</div>
<div>
<br />
</div>
<b>三、bitmap原理解析</b>
</div>
<div>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
bitmap的存储结果相对来说,复杂一点。bitmap不存储rowid,rowid存储在每一个bitmap的头部,都存储了rowid的启示位置与结束位置。ORACLE通过自己的内部算 法,算出来相应的ROWID。<br style="background-color:inherit;" />
位图中的每一位,都记录是否有值。如表的记录是这样存储的:
</p>
<table border="1" cellpadding="2" cellspacing="0" style="font-size:14px;margin-top:10px;margin-bottom:10px;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
<tbody style="background-color:inherit;">
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
row-value
</td>
</tr>
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
male
</td>
</tr>
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
female
</td>
</tr>
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
female
</td>
</tr>
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
male
</td>
</tr>
</tbody>
</table>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
那么对应的bitmap则是这样存储的:
</p>
<table border="1" cellpadding="2" cellspacing="0" width="100%" style="font-size:14px;margin-top:10px;margin-bottom:10px;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
<tbody style="background-color:inherit;">
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
rowid的启示位置与结束位置
</td>
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
rowid的启示位置与结束位置
</td>
</tr>
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
male
</td>
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
female
</td>
</tr>
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
1
</td>
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
0
</td>
</tr>
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
0
</td>
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
1
</td>
</tr>
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
0
</td>
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
1
</td>
</tr>
<tr style="background-color:inherit;">
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
1
</td>
<td style="word-break:break-all;border:1px solid #999999;padding:5px 16px 5px 12px;min-height:25px;min-width:25px;height:25px;background-color:inherit;line-height:1.6;">
0
</td>
</tr>
</tbody>
</table>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
由 此可见,存储的空间大大的节省了,另外带来的收益就是扫描的BLOCK也大大减少了。
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
如果查找性别是male的数据,ORACLE只会去 搜索MALE这一列,然后是1的记录,返回即可。
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
<br />
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
如果是针对BITMAP字段本身做OR,AND这样的查询,那么ORACLE会在BITMAP索引内部,先做一次判断,找出符合结果的,再去计算ROWID,最后给出相应的VALUE,示意图如下:
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;background-color:#FAFAFC;">
<img src="/attachment/201510/8/30208428_1444289696Hga7.gif" width="600" height="176" alt="" />
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;background-color:#FAFAFC;">
<br />
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
<strong style="background-color:inherit;">bitmap join index</strong><br style="background-color:inherit;" />
bitmap join index,它的特点就是将多张表的JOIN结果,存储在一个索引里面,然后使用BITMAP的形式进行存储。这个对于类似DW那样的多表join效率提高很明显。<br style="background-color:inherit;" />
做用3张表join来做测试如下,原来的SQL是这样的:<br style="background-color:inherit;" />
test@DB><span style="line-height:1.5;">select wt_cust.company_name,wt_cust.gmt_create</span>
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
2 from wt_cust,wt_CUST_EXT ,wt_CUST_BOOK<br style="background-color:inherit;" />
3 where wt_cust.id=wt_CUST_EXT.Cust_Id<br style="background-color:inherit;" />
4 and wt_CUST_BOOK.Cust_Id=wt_cust.id;
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
58 rows selected.
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
Elapsed: 00:00:00.01
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
Execution Plan<br style="background-color:inherit;" />
———————————————————-
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
—————————————————————————————————-<br style="background-color:inherit;" />
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|<br style="background-color:inherit;" />
—————————————————————————————————-<br style="background-color:inherit;" />
| 0 | SELECT STATEMENT | | 54 | 2484 | 179 (0)|<br style="background-color:inherit;" />
| 1 | NESTED LOOPS | | 54 | 2484 | 179 (0)|<br style="background-color:inherit;" />
| 2 | NESTED LOOPS | | 177 | 7257 | 179 (0)|<br style="background-color:inherit;" />
<span style="background-color:inherit;color:#FF0000;">| 3 | INDEX FULL SCAN | wt_CUST_BOOK_UK | 177 | 1062 | 1 (0)|<br style="background-color:inherit;" />
| 4 | TABLE ACCESS BY INDEX ROWID| wt_CUST | 1 | 35 | 2 (0)|<br style="background-color:inherit;" />
|* 5 | INDEX UNIQUE SCAN | wt_CUST_PK | 1 | | 1 (0)|<br style="background-color:inherit;" />
|* 6 | INDEX RANGE SCAN | wt_CUST_EXT_CID_IND | 1 | 5 | 0 (0)|</span><br style="background-color:inherit;" />
—————————————————————————————————-
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
一 个3表join,效率很差。如果我们创建BITMAP JOIN INDEX则可以避免这种情况的发生:<br style="background-color:inherit;" />
test@DB>CREATE BITMAP INDEX cust_wt_test<br style="background-color:inherit;" />
2 ON wt_cust(wt_cust.company_name)<br style="background-color:inherit;" />
3 FROM wt_cust,wt_CUST_EXT ,wt_CUST_BOOK<br style="background-color:inherit;" />
4 WHERE wt_cust.id=wt_CUST_EXT.Cust_Id<br style="background-color:inherit;" />
5 and wt_CUST_BOOK.Cust_Id=wt_cust.id<br style="background-color:inherit;" />
6 tablespace test_ind ;
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
Index created.
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
Elapsed: 00:00:00.08<br style="background-color:inherit;" />
再来看看SQL的执行计划:<br style="background-color:inherit;" />
xx@DB>select wt_cust.company_name,wt_cust.gmt_create<br style="background-color:inherit;" />
2 from wt_cust,wt_CUST_EXT ,wt_CUST_BOOK<br style="background-color:inherit;" />
3 where wt_cust.id=wt_CUST_EXT.Cust_Id<br style="background-color:inherit;" />
4 and wt_CUST_BOOK.Cust_Id=wt_cust.id;
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
58 rows selected.
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
Elapsed: 00:00:00.00
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
Execution Plan<br style="background-color:inherit;" />
———————————————————-
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
—————————————————————————————<br style="background-color:inherit;" />
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|<br style="background-color:inherit;" />
—————————————————————————————<br style="background-color:inherit;" />
| 0 | SELECT STATEMENT | | 1834K| 61M| 219K (1)|<br style="background-color:inherit;" />
| 1 | TABLE ACCESS BY INDEX ROWID | wt_CUST | 1834K| 61M| 219K (1)|<br style="background-color:inherit;" />
| 2 | BITMAP CONVERSION TO ROWIDS| | | | |<br style="background-color:inherit;" />
<span style="background-color:inherit;color:#FF0000;">| 3 | BITMAP INDEX FULL SCAN | CUST_WT_TEST | | | |</span><br style="background-color:inherit;" />
—————————————————————————————
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
请 着重注意红色部分。逻辑读大大降低!!
</p>
<p style="font-size:14px;line-height:21px;white-space:normal;widows:auto;color:#333333;font-family:tahoma, 宋体;text-align:justify;background-color:#FAFAFC;">
<br />
</p>
</div>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。