【问题标题】:How are bitmap indexes helpful?位图索引有何帮助?
【发布时间】:2011-03-28 00:23:21
【问题描述】:

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-tree 索引,例如,我们寻找Gender = Male,我们会得到很多结果,这需要进一步过滤掉(所以不是很有用)。位图如何改善这种情况?

【问题讨论】:

    标签: database algorithm database-design indexing bitmap


    【解决方案1】:

    如果给出上面的示例,位图索引的更好表示:

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

    性别列上的位图索引(在概念上)如下所示:

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

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

    所以有了这个索引,查询就像

    SELECT * FROM table1 WHERE gender = 'Male'
    

    数据库在索引中的性别值中查找匹配项,找到该位设置为 1 的所有 rowid,然后去获取表结果。

    这样的查询:

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

    将获得男性的 1 位,未指定的 1 位,执行按位或然后获取结果位为 1 的行。

    因此,与 ab*tree 索引相比,使用位图索引的优势在于存储(基数低,位图索引非常紧凑),以及在解析实际 rowid 之前执行按位运算的能力,这可能非常快。

    请注意,位图索引可能会对插入/删除产生性能影响(从概念上讲,您可以在位图中添加/删除列并相应地对其进行重新调整...),并且可能会在更新时产生大量争用一行可以锁定整个相应的位图条目,并且在提交/回滚第一个更新之前,您不能更新不同的行(具有相同的位图值)。

    【讨论】:

    • 数据库是否会扫描整个位图以查找“未指定”以搜索所有相应的行,还是存在某种查找结构的情况?
    • @Beginner,请参阅此处的“位图存储结构”:docs.oracle.com/database/121/CNCPT/indexiot.htm#CNCPT88851
    • 这是我读过的关于位图索引为何有用的最佳解释。但是,我仍然不清楚的是,为什么在仅搜索 one 列时位图索引会比普通的 b-tree 索引更好。 b-tree 索引应该让我快速确定对应于MaleFemaleMale | Unspecified 的行子集,对吗?
    • @DanLenski - 是的,绝对是,b-tree 索引非常快,位图索引不是它们的一般替代品。我不确定你从哪里得到的印象是位图索引在性能上比 b-tree 更好。如前所述,位图索引相对于 b 树的优势在于存储(索引列的基数较低)和对其他位图索引进行按位运算的能力。 (事实上​​,当您进行大量 DML 时,位图索引实际上会引起麻烦:akadia.com/services/ora_bitmapped_index.html
    • 谢谢,@Patrick Marchand。我读过其他几篇关于位图索引的文章,这些文章表明它们对于单列搜索比 B-tree 更快,这对我来说从来没有任何意义,因为我只能理解它们如何加速搜索多个低 -基数列(感谢按位运算和高效存储)。
    【解决方案2】:

    在过滤多个列时会带来好处,然后可以在实际选择数据之前将相应的索引与按位运算合并。 如果你有性别,eye_colour,hair_colour 然后查询

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

    将首先在 eye_colour['blue'] 索引和 hair_colour['blonde'] 索引之间进行按位或,最后在结果和性别['male'] 索引之间进行按位和。此操作在计算和 I/O 上都执行得非常快。
    生成的比特流将用于挑选实际的行。

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

    【讨论】:

    • 谢谢,很多答案都是按位提到的,而没有像你一样解释它的适用性。
    【解决方案3】:

    正如 Wikipedia 文章中所指出的,它们使用按位运算,这比比较整数等数据类型的性能更好,因此简短的回答是提高查询速度。

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

    只要想一想这在幕后是如何工作的,就应该明白为什么这会更快。位在逻辑上是真或假。如果您想使用 WHERE 子句进行查询,这最终将评估记录的真或假,以确定是否将它们包含在您的结果中。

    前言 - 其余部分是外行的燕鸥和非技术人员

    那么下一个问题是评估为真需要什么?即使比较数值也意味着计算机必须...

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

    如果您使用多部分 where 子句,例如 Where "this = this AND that = that",请重复此操作

    1. 对步骤 5 中生成的结果执行按位运算
    2. 得出最终值
    3. 释放在步骤 1-3 中分配的内存

    但是使用按位逻辑,您只需要查看 0(假)和 1(真)值。消除了 90% 的比较工作开销。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多