8.4.1关于位图索引访问
在常规的B树索引中,一个索引条目指向单个行。在位图索引中,键是索引数据和rowid范围的组合。
数据库为每个索引键至少存储一个位图。位图中的每一个值,这是一系列的1和0值,点到行一个rowid范围内。因此,在位图索引中,一个索引条目指向一组行而不是单个行。
8.4.1.1位图索引与B树索引之间的差异
位图索引使用与B树索引不同的密钥,但存储在B树结构中。
下表显示了索引条目类型之间的差异。
表8-3 B树和位图的索引条目
| 索引输入 | 键 | 数据 | 例 |
|---|---|---|---|
| 唯一B树 | 仅索引数据 | Rowid | 在该 |
非唯一B树 | 索引数据与rowid结合 | 没有 | 在 |
位图 | 索引数据与rowid范围相结合 | Bitmap | 在该 |
数据库将位图索引存储在B树结构中。数据库可以在关键字的第一部分(定义索引的属性集)上快速搜索B树,然后获取相应的rowid范围和位图。
也可以看看:
- “ 位图存储 ”
- Oracle Database Concepts概述位图索引
- 《 Oracle数据库数据仓库指南》中有关位图索引的更多信息
8.4.1.2位图索引的用途
位图索引通常适用于很少或中等数量的不同值(NDV)的不经常修改的数据。
通常,B树索引适用于具有较高NDV和频繁DML活动的列。例如,优化器可能为sales.amount返回很少行的列的查询选择B树索引。相反,customers.state和customers.county列是位图索引的候选项,因为它们几乎没有什么不同的值,不经常更新,并且可以从高效AND和OR运算中受益。
位图索引是加快数据仓库中临时查询的一种有用方法。它们是星型转化的基础。具体来说,位图索引在包含以下内容的查询中很有用:
WHERE子句中的 多个条件在访问表本身之前,数据库会筛选出满足某些(但不是全部)条件的行。
AND,OR以及NOTNDV低或中等例的操作组合位图索引可使这些操作更有效。数据库可以非常快速地合并位图索引中的位图。例如,如果
customers.state和customers.county列上存在位图索引,则这些索引可以极大地提高以下查询的性能:SELECT * FROM customers WHERE state = 'CA' AND county = 'San Mateo'数据库可以将
1合并的位图中的值有效地转换为rowid。- 该
COUNT功能 : 数据库可以扫描位图索引,而无需扫描表。 - 选择空值的谓词 : 与B树索引不同,位图索引可以包含空值。对一列中的空值进行计数的查询可以使用位图索引,而无需扫描表。
- 没有经历繁重的DML的列
原因是一个索引键指向许多行。如果会话修改了索引数据,则数据库无法锁定位图中的单个位:相反,数据库将锁定整个索引条目,实际上,该索引条目将锁定位图所指向的行。例如,如果特定客户的居住县从更改
San Mateo为Alameda,则数据库必须获得对位图中San Mateo索引条目和Alameda索引条目的独占访问权限。直到包含这两个值的行才能被修改COMMIT。
也可以看看:
- 《星际转型》
- Oracle Database SQL语言参考以了解该
COUNT功能
8.4.1.3位图和行标识符
对于位图中的特定值,该值是1行值是否匹配位图条件,0否则不匹配。基于这些值,数据库使用内部算法将位图映射到rowid。
位图条目包含索引值,行ID范围(开始和结束行ID)和位图。位图中的每个0或1值都是rowid范围的偏移量,即使该行不存在,也将映射到表中的潜在行。因为一个块中可能的行数是预先确定的,所以数据库可以使用范围端点来确定范围内任意行的rowid。
注意:
Hakan因子是位图索引算法用于限制Oracle数据库假定可以存储在单个块中的行数的优化。通过人为地限制行数,数据库减少了位图的大小。
表8-4显示了该sh.customers.cust_marital_status列的示例位图的一部分,该位图可以为空。实际索引具有12个不同的值。该示例中仅显示了3个:null married,和single。
表8-4位图索引条目
| cust_marital_status的列值 | 在范围内开始Rowid | 范围内的末端Rowid | 范围中的第一行 | 范围第二行 | 范围第三行 | 范围第四排 | 范围第五行 | 范围第六行 |
|---|---|---|---|---|---|---|---|---|
(空值) |
|
| 0 | 0 | 0 | 0 | 0 | 1个 |
|
|
| 1个 | 0 | 1个 | 1个 | 1个 | 0 |
|
|
| 0 | 1个 | 0 | 0 | 0 | 0 |
|
|
| 1个 | 0 | 1个 | 0 | 1个 | 1个 |
如表8-4所示,与B树索引不同,位图索引可以包含完全由空值组成的键。在表8-4中,null 1的范围内第6行的cust_marital_status值为,这意味着该范围内的第6行的值为null。为某些SQL语句(例如使用聚合函数进行的查询),索引空值可能会很有用COUNT。
也可以看看:
Oracle Database Concepts了解Rowid格式
8.4.1.4位图联接索引
位图连接索引是位图索引用于连接两个或更多的表。
优化器可以使用位图连接索引来减少或消除计划执行期间必须连接的数据量。位图联接索引在存储方面比实例化联接视图要高效得多。
以下示例在sh.sales和sh.customers表上创建一个位图索引:
CREATE BITMAP INDEX cust_sales_bji ON sales(c.cust_city)
FROM sales s, customers c
WHERE c.cust_id = s.cust_id LOCAL;
前面语句中的FROM and WHERE子句CREATE表示表之间的连接条件。该customers.cust_city列是索引键。
索引中的每个键值代表customers表格中可能的城市。从概念上讲,索引的键值可能如下所示,并且每个键值都与一个位图相关联:
San Francisco 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 . . .
San Mateo 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 . . .
Smithville 1 0 0 0 1 0 0 1 0 0 1 0 1 0 0 . . .
.
.
.
位图中的每一位对应于sales表中的一行。在Smithville键中,该值1表示表中的第一行sales对应于出售给Smithville客户的产品,而该值0表示第二行对应于未出售给Smithville客户的产品。
考虑以下查询到史密斯维尔客户的单独销售数量:
SELECT COUNT (*)
FROM sales s, customers c
WHERE c.cust_id = s.cust_id
AND c.cust_city = 'Smithville';
以下计划显示数据库读取Smithville位图以导出Smithville销售的数量(步骤4),从而避免了customers and sales表的联接。
SQL_ID 57s100mh142wy, child number 0
-------------------------------------
SELECT COUNT (*) FROM sales s, customers c WHERE c.cust_id = s.cust_id
AND c.cust_city = 'Smithville'
Plan hash value: 3663491772
------------------------------------------------------------------------------------
|Id| Operation | Name |Rows|Bytes|Cost (%CPU)| Time|Pstart|Pstop|
------------------------------------------------------------------------------------
| 0| SELECT STATEMENT | | | |29 (100)| | | |
| 1| SORT AGGREGATE | | 1 | 5| | | | |
| 2| PARTITION RANGE ALL | | 1708|8540|29 (0)|00:00:01|1|28|
| 3| BITMAP CONVERSION COUNT | | 1708|8540|29 (0)|00:00:01| | |
|*4| BITMAP INDEX SINGLE VALUE|CUST_SALES_BJI| | | | |1|28|
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("S"."SYS_NC00008$"='Smithville')也可以看看:
Oracle Database Concepts了解该CREATE INDEX语句
8.4.1.5位图存储
位图索引位于B树结构中,就像在B树中一样使用分支块和叶块。
例如,如果customers.cust_marital_status列具有12个不同的值,则一个分支块可能指向键A,另一分支块可能指向键B,等等。或者单个分支块可以指向包含所有12个不同键的叶块。married,rowid-rangesingle,rowid-rangewidowed,rowid-range
每个索引列值可以具有一个或多个位图片段,每个片段都有其自己的rowid范围,它们在一个或多个范围内占据了一组连续的行。数据库可以使用位图片段来分解相对于块大小而言较大的索引条目。例如,数据库可以将单个索引条目分成三部分,前两部分在相同范围内的单独块中,最后一块在不同程度的单独块中。
为了节省空间,Oracle数据库可以压缩连续的0值范围。




