2010-08-10 112 views
28

Wikipedia给出了这样的例子位图索引如何提供帮助?

Identifier Gender   Bitmaps 
           F M 
1   Female   1 0 
2   Male    0 1 
3   Male    0 1 
4   Unspecified  0 0 
5   Female   1 0 

但我不明白这一点。

  • 首先这是一个索引?是不是索引应该指向行(使用rowid的)给定的关键?
  • 什么是典型的查询这样的索引是有用的?它们如何比B-tree索引更好?我知道如果我们在Gender这里使用B树索引,我们会得到很多结果,例如,我们寻找Gender = Male,这需要进一步过滤掉(所以不是很有用)。位图如何改善情况?

回答

33

位图索引的更好的表示,则如果给定上述示例:

Identifier Gender   RowID 
1    Female   R1 
2    Male   R2 
3    Male   R3 
4    Unspecified  R4 
5    Female   R5 

的上gender列的位图索引将(在概念上)看起来像这样:

Gender  R1 R2 R3 R4 R5 
Female  1  0 0 0 1 
Male   0  1 1 0 0 
Unspecified 0  0 0 1 0 

位图当一列中的不同值的数量相对较低时使用索引(考虑相反的情况,所有值都是唯一的:位图索引将与每行一样宽,只要使它有点像一个大的身份ma TRIX。)

与该指数的地方查询像

SELECT * FROM table1 WHERE gender = 'Male' 

数据库查找在索引中的性别价值观匹配

所以,找到所有在位被设置为1的rowid,和然后去获得表结果。

喜欢的查询:

SELECT * FROM table1 WHERE gender IN ('Male', 'Unspecified') 

会得到男性的1位,用于在未指定1位,做一个按位或然后去获得,其中所得位是1

行因此,在ab *树索引上使用位图索引的优点是存储(基数小,位图索引非常紧凑),并且能够在解析实际的rowid之前进行按位操作,这很快。

请注意,位图索引可能会对插入/删除产生性能影响(从概念上说,您向位图中添加/移除列并相应地重新调整列...),并且可能会创建大量争用作为更新在一行中可以锁定整个对应的位图条目,并且无法更新另一行(具有相同的位图值),直到提交/回滚第一个更新。

+0

数据库会扫描整个位图的'未指定'来搜索所有相应的行或有一些查找结构的情况吗? – Beginner 2017-03-16 11:07:41

+1

@Beginner,请参阅“位图存储结构”:https://docs.oracle.com/database/121/CNCPT/indexiot.htm#CNCPT88851 – 2017-03-16 18:05:50

+0

这是我读过的最好的解释为什么位图索引可能是有用。然而,我仍然不清楚为什么当仅搜索一列**时,位图索引比正常的B树索引更好。 b-tree索引也应该允许我快速确定与“Male”或“Female”或“Male |”对应的行的子集。未指定',对吗? – 2017-04-01 04:07:12

4

正如维基百科文章中所指出的那样,它们使用按位运算,它可以比比较数据类型(如整数)更好地执行,所以简短答案就是提高查询速度。

从理论上讲,它应该占用更少的计算时间和更少的时间来选择您的示例中的所有男性或所有女性。

只要想一想这是如何在引擎盖下工作的,应该说明为什么这更快显而易见。有一点在逻辑上是真或假。如果您想使用WHERE子句执行查询,那么最终将对记录求值为true或false,以确定是否将它们包含在结果中。

前言 - 这剩下的,就是要外行的燕鸥和非技术人员

因此,接下来的问题是,怎样才能评估为真?即使是比较数值意味着计算机有...

  1. 分配内存要评估
  2. 分配内存控制值
  3. 赋值给每个(算上这两个值步骤)
  4. 比较两个 - 对于数字,这应该是快速的,但对于字符串,有更多的字节进行比较。
  5. 将结果赋值为0(假)或1(真)值。

重复如果您使用多部分where子句诸如在哪里“这个=这个那个=认为”

  • 上所产生的结果执行位操作第5步
  • 拿出最终值
  • 解除分配内存使用逐逻辑步骤1-3
  • 但分配的,你只是在看0(假)和1(真)值。比较工作的90%的开销被消除了。

    12

    在对多列进行过滤时,可以在实际选择数据之前将相应的索引与位操作进行合并。 如果你有性别,eye_colour,hair_colour 那么查询

    select * from persons where 
             gender = 'male' and 
             (eye_colour = 'blue' or hair_colour = 'blonde') 
    

    会首先做一个按位或eye_colour [“蓝色”]指数和hair_colour [“金发女郎”]指数之间终于按位之间的结果和性别['男性']指数。这个操作在计算和I/O方面都非常快。
    生成的比特流将用于拾取实际行。

    位图索引通常用于数据仓库应用程序中的“星型连接”。