热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

Oracle位图索引(BitmapIndex)

欢迎进入Oracle社区论坛,与200万技术人员互动交流进入位图(bitmap)索引是另外一种索引类型,它的组织形式与B树索引相同,也是一棵平衡树。与B树索引的区别在于叶子节点里存放索引条目的方式不同。从前面我们知道,B树索引的叶子节点里,对于表里的每

欢迎进入Oracle社区论坛,与200万技术人员互动交流 >>进入 位图(bitmap)索引是另外一种索引类型,它的组织形式与B树索引相同,也是一棵平衡树。与B树索引的区别在于叶子节点里存放索引条目的方式不同。从前面我们知道,B树索引的叶子节点里,对于表里的每

欢迎进入Oracle社区论坛,与200万技术人员互动交流 >>进入

  位图(bitmap)索引是另外一种索引类型,它的组织形式与B树索引相同,也是一棵平衡树。与B树索引的区别在于叶子节点里存放索引条目的方式不同。从前面我们知道,B树索引的叶子节点里,对于表里的每个数据行,如果被索引列的值不为空的,则会为该记录行在叶子节点里维护一个对应的索引条目。

  而位图索引则不是这样,其叶子节点里存放的索引条目如下图所示。

  假设某个表T里所有的记录在列C1上只具有三个值:01、02和03。在表T的C1列上创建位图索引以后,则叶子节点的内容如图9-14所示。可以看到,位图索引只有三个索引条目,也就是每个C1列的值对应一个索引条目。位图索引条目上还包含表里第一条记录所对应的ROWID以及最后一条记录所对应的ROWID。索引条目的最后一部分则是由多个bit位所组成的bitmap,每个bit位就对应一条记录。

  位图索引的结构

  当发出where c1=’01’这样的SQL语句时,oracle会去搜索01所在的索引条目,然后扫描该索引条目中的bitmap里所有的bit位。第一个bit位为1,则说明第一条记录上的C1值为01,于是返回第一条记录所在的ROWID(根据该索引条目里记录的start ROWID加上行号得到该记录所在的ROWID)。第二个bit位为0,则说明第二条记录上的C1值不为01,依此类推。另外,如果索引列为空,也会在位图索引里记录,也就是将对应的bit位设置为0即可。

  如果索引列上不同值的个数比较少的时候,比如对于性别列(男或女)等,则使用位图索引会比较好,因为它对空间的占用非常少(因为都是用bit位来表示表里的数据行),从而在扫描索引的时候,扫描的索引块的个数也比较少。可以试想一下,如果在列的不同值非常多的列上,比如主键列上,创建位图索引,则产生的索引条目就等于表里记录的条数,同时每个索引条目里的bitmap里,只有一个1,其它都是0。这样还不如B树索引的效率高。

  如果被索引的列经常被更新的话,则不适合使用位图索引。因为当更新位图所在的列时,由于要在不同的索引条目之间修改bit位,比如将第一条记录从01变为02,则必须将01所在的索引条目的第一个bit位改为0,再将02所在的索引条目的第一个bit位改为1。因此,在更新索引条目的过程中,会锁定位图索引里多个索引条目。也就是同时只能有一个用户能够更新表T,从而降低了并发性。

  位图索引比较适合用在数据仓库系统里,不适合用在OLTP系统里。

  SQL> create table t_bitmap_test as

  2 select rownum as id,trunc(dbms_random.value(1,4)) as bitcol

  3 from dba_objects where rownum<=20;

  SQL> select * from t_bitmap_test;

  ID BITCOL

  ---------- ----------

  1 3

  2 2

  3 1

  4 3

  5 3

  6 1

  7 1

  8 2

  9 3

  10 2

  11 3

  12 1

  13 1

  14 3

  15 2

  16 2

  17 3

  18 2

  19 1

  20 3

  SQL> connect hr/hr

  已连接。

  SQL> alter session set events '10608 trace name context forever, level 10';

  会话已更改。

  SQL> create bitmap index idx_t_bitmap_test on t_bitmap_test(bitcol);

  索引已创建。

  SQL> alter session set events '10608 trace name context off';

  会话已更改。

  SQL> select object_id from user_objects where object_name='IDX_T_BITMAP_TEST';

  OBJECT_ID

  ----------

  24499

  SQL> alter session set events 'immediate trace name TREEDUMP level 24499';

  会话已更改。

  10608事件用来跟踪创建bitmap索引的过程。而TREEDUMP则用来转储索引的树状结构。打开转储出来的文件:

  *** SESSION ID:(7.13) 2008-06-10 14:33:46.000

  qerbiARwo: bitmap size is 8168

  qerbiIPI default pctfree=10

  qerbiIPI length=0

  qerbiAllocate pfree=127 space=8168

  qerbiStart first start

  qerbiRop: rid=00c01ce4.0000, new=Y , key: (2): c1 04

  qerbiCmpSz notfound pctfree=10

  qerbiCmpSz adjblksize=7351 length=0

  qerbiRop keysize=4 maxbm=3531

  kdibcoinit(3116714): srid=00c01ce4.0000

  qerbiRop: rid=00c01ce4.0001, new=Y , key: (2): c1 03

  kdibcoinit(3116698): srid=00c01ce4.0001

  qerbiRop: rid=00c01ce4.0002, new=Y , key: (2): c1 02

  kdibcoinit(311661c): srid=00c01ce4.0002

  qerbiRop: rid=00c01ce4.0003, new=N, key: (2): c1 04

  qerbiRop: rid=00c01ce4.0004, new=N, key: (2): c1 04

  qerbiRop: rid=00c01ce4.0005, new=N, key: (2): c1 02

  qerbiRop: rid=00c01ce4.0006, new=N, key: (2): c1 02

  qerbiRop: rid=00c01ce4.0007, new=N, key: (2): c1 03

  qerbiRop: rid=00c01ce4.0008, new=N, key: (2): c1 04

  qerbiRop: rid=00c01ce4.0009, new=N, key: (2): c1 03

  qerbiRop: rid=00c01ce4.000a, new=N, key: (2): c1 04

  qerbiRop: rid=00c01ce4.000b, new=N, key: (2): c1 02

  qerbiRop: rid=00c01ce4.000c, new=N, key: (2): c1 02

  qerbiRop: rid=00c01ce4.000d, new=N, key: (2): c1 04

  qerbiRop: rid=00c01ce4.000e, new=N, key: (2): c1 03

  qerbiRop: rid=00c01ce4.000f, new=N, key: (2): c1 03

  qerbiRop: rid=00c01ce4.0010, new=N, key: (2): c1 04

  qerbiRop: rid=00c01ce4.0011, new=N, key: (2): c1 03

  qerbiRop: rid=00c01ce4.0012, new=N, key: (2): c1 02

  qerbiRop: rid=00c01ce4.0013, new=N, key: (2): c1 04

  kdibcoend(3116714): erid=00c01ce4.0017status=3

[1] [2] [3]


推荐阅读
  • 本文详细介绍了IBM DB2数据库在大型应用系统中的应用,强调其卓越的可扩展性和多环境支持能力。文章深入分析了DB2在数据利用性、完整性、安全性和恢复性方面的优势,并提供了优化建议以提升其在不同规模应用程序中的表现。 ... [详细]
  • 本文介绍了如何使用 PostgreSQL 的 `UPDATE ... FROM` 语法,通过映射表实现对多行记录进行高效的批量更新。这种方法不仅适用于单列更新,还支持多列的同时更新。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 本文详细介绍了HTML中标签的使用方法和作用。通过具体示例,解释了如何利用标签为网页中的缩写和简称提供完整解释,并探讨了其在提高可读性和搜索引擎优化方面的优势。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 本文探讨了适用于Spring Boot应用程序的Web版SQL管理工具,这些工具不仅支持H2数据库,还能够处理MySQL和Oracle等主流数据库的表结构修改。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 在使用 DataGridView 时,如果在当前单元格中输入内容但光标未移开,点击保存按钮后,输入的内容可能无法保存。只有当光标离开单元格后,才能成功保存数据。本文将探讨如何通过调用 DataGridView 的内置方法解决此问题。 ... [详细]
  • 本文详细介绍了如何在 Linux 平台上安装和配置 PostgreSQL 数据库。通过访问官方资源并遵循特定的操作步骤,用户可以在不同发行版(如 Ubuntu 和 Red Hat)上顺利完成 PostgreSQL 的安装。 ... [详细]
  • 如何在PostgreSQL中查看数据表
    本文将指导您使用pgAdmin工具连接到PostgreSQL数据库,并展示如何浏览和查找其中的数据表。通过简单的步骤,您可以轻松访问所需的表结构和数据。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
author-avatar
馨海之洋_895
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有