精华内容
下载资源
问答
  • 位图索引简单实验

    2018-06-21 18:04:11
    比较B*树索引和位图索引位图索引更加适合重复值较大的值。
  • 位图索引压缩中的设计空间仍然是一个富有成果的未知前沿,值得探索。 我们在 FastBit 中引入 PLWAH(位置列表字对齐混合)编码作为测试我们新设计的名为 SECOMPAX 和许多其他位图索引压缩方案的基准。 SECOMPAX ...
  • 位图索引

    2018-08-01 16:25:00
    位图索引特别不适用于OLTP系统,如果系统中的数据会由多个并发会话频繁地更新,这种系统也不适用位图索引位图索引是这样一种结构,其中 用一个索引键条目存储指向多行的指针 ;这与B*树结构不同,在B*树结构中...

    位图索引(bitmap index)是从Oracle7.3版本开始引入的。目前Oracle企业版和个人版都支持位图索引,但标准版不支持。位图索引是为数据仓库/即席查询环境设计的,在此所有查询要求的数据在系统实现时根本不知道。位图索引特别不适用于OLTP系统,如果系统中的数据会由多个并发会话频繁地更新,这种系统也不适用位图索引。

    位图索引是这样一种结构,其中用一个索引键条目存储指向多行的指针;这与B*树结构不同,在B*树结构中,索引键和表中的行存在着对应关系。在位图索引中,可能只有很少的索引条目,每个索引条目指向多行。而在传统的B*树中,一个索引条目就指向一行。

    下面假设我们要在EMP表的JOB列上创建一个位图索引,如下:

    system@ORCL>create BITMAP index job_idx on emp(job);
    
    索引已创建。
    

    Oracle 在索引中存储的内容如表 11-6 所示。

    表 11-6 Oracle 如何存储 JOB-IDX 位图索引

    值/行

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    ANALYST 

    0

    0

    0

    0

    0

    0

    0

    1

    0

    1

    0

    0

    1

    0

    CLERK 

    1

    0

    0

    0

    0

    0

    0

    0

    0

    0

    1

    1

    0

    1

    MANAGER 

    0

    0

    0

    1

    0

    1

    1

    0

    0

    0

    0

    0

    0

    0

    PRESIDENT 

    0

    0

    0

    0

    0

    0

    0

    0

    1

    0

    0

    0

    0

    0

    SALESMAN 

    0

    1

    1

    0

    1

    0

    0

    0

    0

    0

    0

    0

    0

    0

    表11-6显示了第8、10和13行的值为ANALYST,而第4、6和7行的值为MANAGER。在此还显示了所有行都不为null(位图索引可以存储null条目;如果索引中没有null条目,这说明表中没有null行)。如果我们想统计值为MANAGER的行数,位图索引就能很快地完成这个任务。如果我们想找出JOB为CLERK或MANAGER的所有行,只需根据索引合并它们的位图,如表11-7所示。

    表 11-7 位 OR 的表示

    值/行

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    CLERK 

    1

    0

    0

    0

    0

    0

    0

    0

    0

    0

    1

    1

    0

    1

    MANAGER 

    0

    0

    0

    1

    0

    1

    1

    0

    0

    0

    0

    0

    0

    0

    CLERK或MANAGER 

    1

    0

    0

    1

    0

    1

    1

    0

    0

    0

    1

    1

    0

    1

    表11-7清楚地显示出,第1、4、6、7、11、12、14行满足我们的要求。Oracle如下为每个键值存储位图,使得每个位置表示底层表中的一个rowid,以后如果确实需要访问行时,可以利用这个rowid进行处理。对于以下查询:

    system@ORCL>select count(*) from emp where job = 'CLERK' or job = 'MANAGER';
    
      COUNT(*)
    ----------
             7

    用位图索引就能直接得出答案。另一方面,对于以下查询:

    system@ORCL>select * from emp where job = 'CLERK' or job = 'MANAGER';
    
         EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM
        DEPTNO
    ---------- ---------- --------- ---------- -------------- ---------- ----------
    ----------
          7369 SMITH      CLERK           7902 17-12月-80          32387
            20
          7566 JONES      MANAGER         7839 02-4月 -81          34562
            20
          7698 BLAKE      MANAGER         7839 01-5月 -81          34437
            30
          7782 CLARK      MANAGER         7839 09-6月 -81          34037
            10
          7876 ADAMS      CLERK           7788 23-5月 -87       34321.35
            20
          7900 JAMES      CLERK           7698 03-12月-81          32537
            30
          7934 MILLER     CLERK           7782 23-1月 -82          32887
            10
    
    已选择7行。

    则需要访问表。在此Oracle会应用一个函数把位图中的第i位转换为一个rowid,从而可用于访问表。

    3.1什么情况下应该使用位图索引?

    位图索引对于相异基数(distinct cardinality)低的数据最为合适(也就是说,与职工数据集的基数相比,这个数据只有很少几个不同的值)。对此做出量化是不太可能的——换句话说,很难定义低相异基数到底是多大。在一个有几千条记录的数据集中,2就是一个低相异基数,但是在一个只有两行的表中,2就不能算是低相异基数了。而在一个有上千万或上亿条记录的表中,甚至100,000都能作为一个低相异基数。所以,多大才算是低相异基数,这要相对于结果集的大小来说。这是指,行集中不同项的个数除以行数应该是一个很小的数(接近于0)。例如,GENDER列可能取值为M、F和NULL。如果一个表中有20,000条员工记录,那么3/20000=0.00015。类似地,如果有100,000个不同的值,与11.,000,000条结果相比,比值为0.01,同样这也很小(可算是低相异基数)。这些列就可以建立位图索引。它们可能不适合建立B*树索引,因为每个值可能会获取表中的大量数据(占很大百分比)。如前所述,B*树索引一般来讲应当是选择性的。与之相反,位图索引不应是选择性的,一般来讲它们应该“没有选择性“。

    如果有大量即席查询,特别是查询以一种即席方式引用了多列或者会生成诸如COUNT之类的聚合,在这样的环境中,位图索引就特别有用。例如,假设你有一个很大的表,其中有3列:GENDER、LOCATION和AGE_GROUP。在这个表中,GENDER只有两个可取值:M或F,LOCATION可取值为11.50,AGE_GROUP是一个代码,分别表示11. and under(11.及以下)、11.-25、26-30、31-40和41 and over(41及以上)。

    在一个数据仓库或支持多个即席SQL查询的大型报告系统中,能同时合理地使用尽可能多的索引确实非常有用。
    位图索引在读密集的环境中能很好地工作,但是对于写密集的环境则极不适用。原因在于,一个位图索引键条目指向多行。如果一个会话修改了所索引的数据,那么在大多数情况下,这个索引条目指向的所有行都会被锁定。Oracle无 法锁定一个位图索引条目中的单独一位;而是会锁定这个位图索引条目。倘若其他修改也需要更新同样的这个位图索引条目,就会被“关在门外“。这样将大大影响 并发性,因为每个更新都有可能锁定数百行,不允许并发地更新它们的位图列。在此不是像你所想的那样锁定每一行,而是会锁定很多行。

     

    位图联结索引 (bitmap join index)

    它允许使用另外某个表的列对一个给定表建立索引。实际上,这就允许对一个索引结构(而不是表本身)中的数据进行逆规范化。

    考虑简单的EMP表和DEPT表。EMP有指向DEPT的一个外键(DEPTNO列)。DEPT表有一个DNAME属性(部门名)。

    运行的查询如下所示:

    system@ORCL>select count(*)
      2  from emp, dept
      3  where emp.deptno = dept.deptno
      4  and dept.dname = 'SALES'
      5  /
    
      COUNT(*)
    ----------
             6
    
    system@ORCL>select emp.*
      2  from emp, dept
      3  where emp.deptno = dept.deptno
      4  and dept.dname = 'SALES'
      5  /
    
         EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM
        DEPTNO
    ---------- ---------- --------- ---------- -------------- ---------- ----------
    ----------
          7499 ALLEN      SALESMAN        7698 20-2月 -81          33187        300
            30
          7521 WARD       SALESMAN        7698 22-2月 -81          32837        500
            30
          7654 MARTIN     SALESMAN        7698 28-9月 -81          32837       1400
            30
          7698 BLAKE      MANAGER         7839 01-5月 -81          34437
            30
          7844 TURNER     SALESMAN        7698 08-9月 -81          33087          0
            30
          7900 JAMES      CLERK           7698 03-12月-81          32537
            30
    
    已选择6行。

    利用位图联结索引,我们能对DEPT.DNAME列建立索引,但这个索引不是指向DEPT表,而是指向EMP表。这是一个全新的概念:能从其他表对某个表的属性建立索引。

    以下创建的索引:

    system@ORCL>create bitmap index emp_bm_idx
      2  on emp( d.dname )
      3  from emp e, dept d
      4  where e.deptno = d.deptno
      5  /
    
    索引已创建。

    它会在表上创建索引INDEX_NAME。在此引用了DEPT表中的一列:D.DNAME。这里有一个FROM子句,使这个CREATE INDEX语句有些像查询。另外,多个表之间有一个联结条件。这个CREATE INDEX语句对DEPT.DNAME列建立了索引,但这在EMP表的上下文中。数据库根本不会访问DEPT,而且也不需要访问DEPT,因为DNAME列现在是在指向EMP表中的行的索引中。为了便于说明,我们把EMP表和DEPT表制作得看上去很”大“(以避免CBO认为它们很小,以至于选择执行全面扫描,而不是使用索引):

    system@ORCL>begin
      2  dbms_stats.set_table_stats( user, 'EMP',
      3  numrows => 1000000, numblks => 300000 );
      4  dbms_stats.set_table_stats( user, 'DEPT',
      5  numrows => 100000, numblks => 30000 );
      6  end;
      7  /
    
    PL/SQL 过程已成功完成。

    然后再执行查询:

    system@ORCL>set autotrace traceonly explain
    system@ORCL>select count(*)
      2  from emp, dept
      3  where emp.deptno = dept.deptno
      4  and dept.dname = 'SALES'
      5  /
    
    执行计划
    ----------------------------------------------------------
    Plan hash value: 2538954156
    
    --------------------------------------------------------------------------------
    ----------
    | Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)|
    Time     |
    --------------------------------------------------------------------------------
    ----------
    |   0 | SELECT STATEMENT            |            |     1 |     3 |     1   (0)|
    00:00:01 |
    |   1 |  SORT AGGREGATE             |            |     1 |     3 |            |
             |
    |   2 |   BITMAP CONVERSION COUNT   |            |   333K|   976K|     1   (0)|
    00:00:01 |
    |*  3 |    BITMAP INDEX SINGLE VALUE| EMP_BM_IDX |       |       |            |
             |
    --------------------------------------------------------------------------------
    ----------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - access("EMP"."SYS_NC00009$"='SALES')
    
    system@ORCL>select emp.*
      2  from emp, dept
      3  where emp.deptno = dept.deptno
      4  and dept.dname = 'SALES'
      5  /
    
    执行计划
    ----------------------------------------------------------
    Plan hash value: 615168685
    
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |  6249M|   296G|   133K (34)| 00:26:43 |
    |*  1 |  HASH JOIN         |      |  6249M|   296G|   133K (34)| 00:26:43 |
    |*  2 |   TABLE ACCESS FULL| DEPT | 25000 |   317K|  8143   (1)| 00:01:38 |
    |   3 |   TABLE ACCESS FULL| EMP  |  1000K|    36M| 81422   (1)| 00:16:18 |
    ---------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
       2 - filter("DEPT"."DNAME"='SALES')

    位图联结索引确实有一个先决条件。联结条件必须联结到另一个表中的主键或惟一键。

    转载于:https://my.oschina.net/u/1862478/blog/1920952

    展开全文
  • SPLWAH:用于在档案Internet流量中进行搜索的位图索引压缩方案
  • 开源的分布式位图索引。 想要贡献? 最简单的方法之一就是 。 我们从每一次讨论中学习! 文件 有关安装和使用Pilosa的信息,请参见我们的。 入门 。 使用默认配置 : pilosa server 并确认它正在运行: curl ...
  • 在ITAS的三项关键技术中,我们重点研究位图索引压缩算法,并在本文中进行了详细的调查。当前最新的位图索引编码方案包括:BBC,WAH,PLWAH,EWAH,PWAH,CONCISE,COMPAX,VLC,DF-WAH和VAL-WAH。基于分段,分块,...
  • 一 前言: •ROWID:包含键值的行的行ID,(查找块的最快方法,类似于门牌号) ...二 索引在结构上的类别可划分如下:B树索引、位图索引、散列索引、反转索引等 三 索引的介绍: 1、B树索引(BTREE ...

    一  前言:
    • ROWID:包含键值的行的行ID,(查找块的最快方法,类似于门牌号
    • 因为所有行属于同一个段,所以要使用受限的ROWID 指向表行

    索引是数据库为了提高查询效率提供的一种冗余结构,保守计算数据库50%以上的调优可以通过调整索引来进行优化;

     

    二  索引在结构上的类别可划分如下:B树索引、位图索引、散列索引、反转索引等

    三  索引的介绍:

    1、B树索引(BTREE

    B数索引是我们日常工作最最常用的索引,大家平时在工作中说的"索引"默认都是B数索引;

    索引其实很简单,也很容易理解,用一本书的目录来形容最为贴切了,B树索引的结构跟图书馆的目录也很像

    B树索引的结构:

    索引的顶层为根,它包括指向索引中下一层次的条目。下一层次为分支块,它又指向位于索引中下一层索引中下一层次的块,最底层的是叶节点,它包含指向表行的索引条目。叶块是双向关联的,这边与按键值升序或降序扫描索引;

     

    索引叶条目的格式

    一个索引条目包含以下组件:

    • 条目头:存储列数和锁定信息

    • 键列长度/值对:用于定义键中的列大小,后面跟随列值(此类长度/值对的数目就是索引中的最大列数)。

     

    索引叶条目的特性

    在非分区表的B 树索引中:

    • 当多个行具有相同的键值时,如果不压缩索引,键值会出现重复

    • 当某行包含的所有键列为NULL 时,该行没有对应的索引条目。因此,当WHERE 子句指定了NULL 时,将始终执行全表扫描

     

    对索引执行DML 操作的效果

    对表执行DML 操作时,Oracle 服务器会维护所有索引。下面说明对索引执行DML 命令产生的效果:

    • 执行插入操作导致在相应块中插入索引条目。

    • 删除一行只导致对索引条目进行逻辑删除。已删除行所占用的空间不可供后面新的叶条目使用。

    • 更新键列导致对索引进行逻辑删除和插入。PCTFREE 设置对索引没有影响,但创建时除外。即使索引块的空间少于PCTFREE 指定的空间,也可以向索引块添加新条目。

    该图更能体现索引的结构

     

    2、位图索引

    位图索引(bitmap index)是从Oracle7.3 版本开始引入的。目前Oracle 企业版和个人版都支持位图索引,但标准版不支持。

    位图索引在平时的OLTP系统中比较少见,但是在OLAP系统中就会经常见到,号称数据仓库调优的三个利器之一;

     

    位图索引(通过在以下特定情况下,位图索引比B 树索引更有优势:

    • 表具有数百万行且键列的基数较低时(也就是列的不同值极少时)。例如,对于护照记录表中的性别和婚姻状况列,位图索引可能比B 树索引更可取。

    • 经常使用包含OR 运算符的多个WHERE 条件组合进行查询时

    • 键列上的活动为只读活动或少量更新活动时(OLAP系统的特点)

     

    位图索引的结构

    位图索引也可以按B 树形式进行组织,但是,叶节点会存储每个键值的位图,而不是行ID 列表。位图中每一位与一个可能的行ID 对应,如果设置了该位,则表示具有对应行ID 的行包含键值。

    如图所示,位图索引的叶节点包含:

    • 条目头,其中包含列数和锁定信息

    • 由每个键列的长度/值对组成的键值(在幻灯片的示例中,关键字只由一列组成;第一个条目的键值为Blue)

    • 开始ROWID,在本示例中它指定块号10、行号0 和文件号3

    • 结束ROWID,在本示例中它指定块号12、行号8 和文件号3

    • 由位字符串组成的位图段(如果对应行包含键值,则会设置位;如果对应行不包含键值,则不会设置位。Oracle 服务器使用已获专利的压缩技术存储位图段。)开始ROWID 是位图中的位图段指向的第一行的行ID,也就是说,位图的第一位对应于该行ID,位图的第二位对应于块中的下一行。结束ROWID 是一个指针,它指向由位图段覆盖的表中的最后一行。位图索引使用受限的行ID。

     

    使用位图索引

    B 树用于定位叶节点,这些节点包含指定键值的位图段。开始ROWID 和位图段用于定位包含键值的行。

    对表中的键列进行更改后,也必须修改位图。这会导致相关的位图段被锁定。由于锁是在整个位图段上获得的,因此,在第一个事务处理结束之前,其它事务处理不能更新位图覆盖的行。

     

    理论文章会告诉你值重复率高的字段不适合建索引。不要说性别字段只有两个值,网友亲测,一个字段使用拼音首字母做值,共有26种可能,加上索引后,百万加的数据量,使用索引的速度比不使用索引要慢!

    一个表可能会涉及两个数据结构(文件),一个是表本身,存放表中的数据,另一个是索引。索引是什么?它就是把一个或几个字段(组合索引)按规律排列起来,再附上该字段所在行数据的物理地址(位于表中)。比如我们有个字段是年龄,如果要选取某个年龄段的所有行,那么一般情况下可能需要进行一次全表扫描。但如果以这个年龄段建个索引,那么索引中会按年龄值建一个排列,这样在索引中就能迅速定位,不需要进行全表扫描。

    为什么性别不适合建索引呢?因为你访问索引需要付出额外的IO开销,你从索引中拿到的只是地址,要想真正访问到数据还是要对表进行一次IO。假如你要从表的100万行数据中取几个数据,那么利用索引迅速定位,访问索引的这IO开销就非常值了。但如果你是从100万行数据中取50万行数据,就比如性别字段,那你相对需要访问50万次索引,再访问50万次表,加起来的开销并不会比直接对表进行一次完整扫描小。同时,虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行 INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据还要更新索引。建立索引会占用磁盘空间。一般情 况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。

    当然凡事不是绝对,如果把性别字段设为表的聚集索引,那么就肯定能加快大约一半该字段的查询速度了。聚集索引指的是表本身中数据按哪个字段的值来进行排序。因此,聚集索引只能有一个,而且使用聚集索引不会付出额外IO开销。当然你得能舍得把聚集索引这么宝贵资源用到性别字段上。

     

    (键值重复高的字段也可以建立位图索引)

    B树索引是一对一的,一个索引条目指向一行,而位图索引中索引条目非常少,每个条目指向多行,它适合一些特殊的环境,单纯的比较他们的环境是没有意义的,因为应用的环境不一样。

     

     

    展开全文
  • Oracle关于位图索引的创建与应用

    千次阅读 2018-03-18 13:05:01
    Oracle关于位图索引的创建与应用 标签: Oracle 位图索引 2016年03月13日 10:55:383730人阅读 评论(0) 收藏 举报  分类: 数据库(10) oracle(12)  1)创建  CREATE ...
     

    Oracle关于位图索引的创建与应用

    标签: Oracle 位图索引
    3730人阅读  评论(0)  收藏  举报
      分类:
     
    1)创建

      CREATE BITMAP INDEX index_name ON normal_index_creation_clause;

      Oracle创建一系列的位图,每个位图都与一个特殊的值有关。例如,如果在某一个字段上创建一个位图索引,这个字段上的值有2种,1个是'East'1个是'Central',那没就建立有2个位图,1个用于'East'1个用于'Central'。


      如果索引建立于多个字段上,那么每种可能的组合都必须有一个位图。


      2)位图索引结构

      一个规则的B*tree索引是根据ROWID作为行的关键值来成对,再将这些对整理放置到B*tree结构中。ROWID作为一个指向一行的指针。位图索引有一个非常不一样的结构:ROWID并不直接存储:每个不同的值有一个它们自己的位图。(这就是为什么位图索引通常建立在独特值较少的列上)。


      位图的每个位置映射到一个可能的ROWID上,位图上每个位置的内容用于表示该行特定的值是否在位图列中。所以,位图的每个位置存储特殊行和相关ROWID的信息。如果该ROWID的行的值匹配,则该特殊rowid位置存储为"1",否则储存为"0"。Oracle也能够压缩位图存储。


      3)何时使用位图索引


      - 该字段具有较低的集的势:独特值较少


      - 位图索引在具有冗长WHERE条件的复杂查询或聚合查询(包含SUM,COUNT或其他聚合函数)中特别有帮助。


      - 表中有大量的行(100万行有1万个独特值可以接收使用位图索引)


      - 表上有频繁复杂查询


      - 数据库环境为数据仓库(DSS系统)。由于位图索引的加锁形式,所以它不大适合联机事务处理(OLTP)环境。不能单独锁定位图的其中一个位置。


      位图被锁定的最小数量为1个位图段,它可以达到半个数据块的大小。改变一行的值将会导致整个位图段被锁,同时锁住了其他的行。


      这对于用户如果有大量的UPDATE,INSERT,DELETE语句及其不利。但对于数据是批量导入或更新则没有问题,如在一个数据仓库系统中。


      - 位图连接索引是9i引入的一个新方法,可以避免在运行时的连接操作,因为在索引创建时位图索引已经基于了连接。


      BJI是一个在空间上减少选择数据量的有效方法。这些数据导致的连接操作和限制都永久地存储在BJI中。连接条件是一个相对的内部连接,维度表的主键和事实表的外键。


      4)限制条件


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


      - 位图索引在Trusted Oracle中不支持


      - 不能被规则优化器(RBO)使用


      - 不能用于分区表的全局索引


      - 位图索引不支持build或rebuild的ONLINE选项,在10.2中,只有位图连接索引不支持,普通位图索引可以指定ONLINE选项。


      - 对于有直接装载的位图索引,不提供SORTED_INDEX标记


      - 位图索引不能用于完整性检查


      - 位图索引不能定义为UNIQUE


      - 9i之前,不能在索引组织表上创建位图索引,9i开始支持在索引组织表上创建位图索引:在IOT上创建位图索引要求有一个映射表。


      - 不能给域索引指定BITMAP


      5)相对B*tree索引的优势


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


      - 在大量复杂查询中节省响应时间


      - 对于常规的B*tree索引,有效地节省了空间使用


      a)在某一个字段上只有少量的独特值:


      如果在一个具有唯一性的字段上建立位图索引,那么它要求的空间大大超过B*tree索引。然而,对于每个值都重复了成百上千次,位图索引通常小于常规B*tree索引的25%。位图自身采用压缩格式存储。


      b)如果多个列被索引


      相对于多列(或连接)的B*tree索引,位图索引节约了相当可观的存储。在一个只有B*tree索引的数据库中,必须要预先评估在当个查询中可能访问到的列,然后在这些列上创建组合索引。


      这类索引不仅需要大量的空间,而且要求要有一定的顺序,如一个B*tree索引建立在(MARITAL_STATUS,REGION,GENDER)字段上,查询只访问REGION,GENDER时,索引是不起效果的。为了在数据库中充分地使用索引,必须在这些列上变换另一种排列顺序建立索引。举个简单例子,在一个较低的集的势的3个列中,那么可能就存在有6种位置关系不同的组合索引。需要在磁盘空间和性能之前权衡考虑创建何种位置顺序的索引。位图索引解决了这个进退两难问题。位图索引在查询执行过程中可以有效地组合,所以3个较小的单个字段的位图索引可以完成6种3个字段组合的B*tree索引的工作。


      - 非常高效的并行DML和装载


      位图索引在数据仓库应用中很有效率,但是不适合在OLTP应用系统中使用,因为有大量同时发生的INSERT,UPDATE,DELETE操作。索引直到每个DML操作完成之后才进行维护。例如,如果插入1000行数据,插入的行将放置在排序缓冲区中,然后更新批量更新所有的1000条索引条目。(这就是为什么SORT_AREA_SIZE需要设置为一个较优性能的值,用于位图索引的插入和更新)。所以,每个DML操作,位图段只更新一次,即使段中有多行变更时。


      - 行包含null值(见"位图索引和NULLs")


      6)使用小贴士


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


      - 在所有可能非空的字段上声明NOT NULL约束,可以减少存储需求,因为位图不会有NULL值。


      - 使用固定长度的数据格式可以减少存储需求。


      - 增大CREATE_BITMAP_AREA_SIZE初始化参数,可以加快查询处理


      该参数决定了分配给位图创建的内存大小,默认值为8MB。更大的值可以支持更大的连续位图,所以可以较快查询处理。


      - 增大BITMAP_MERGE_AREA_SIZE初始化参数可以加快索引的范围扫描。该参数决定了索引范围扫描时合并位图分配的内存大小。默认值为1MB。


      7)位图索引示例


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


      1个公司的客户数据


      CUSTOMER#   MARITAL_STATUS   REGION   GENDER  INCOME_LEVEL


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


      101        single           east     male    bracket_1


      102        married          central  female  bracket_4


      103        married          west     female  bracket_2


      104        divorced         west     male    bracket_4


      105        single           central  female  bracket_2


      106        married          central  female  bracket_3


      MARITAL_STATUS,REGION,GENDER,INCOME_LEVEL字段都是有较少的独特值(婚姻状况和地域只有三种值,性别只有2种值,收入级别只有4种值),较为适合在这些字段上创建位图索引。但在CUSTOMER#上不适合创建位图索引,因为该字段独特值较多。


      相反,在该字段上创建一个唯一的B*tree索引,将十分有效。


      本例中,REGION字段上的位图索引。


      由三个分开的位图组成,每个region一个。


      REGION='east'  REGION='central'  REGION='west'  ##       CUSTOMER#


      1              0                 0              <==       101


      0              1                 0              <==       102


      0              0                 1              <==       103


      0              0                 1              <==       104


      0              1                 0              <==       105


      0              1                 0              <==       106


      位图中的每个条目(或是说"bit")对应CUSTOMER表中的每一行。每个bit的值依赖于表中相应行的值。例如,REGION='east'的位图,它的第一个bit为1。这是因为CUSTOMER表的第一行,REGION='east'。REGION='east'的位图其他bit为0,是因为该表的其他行的REGION字段为其他值。


      一个分析员调查该公司客户的人口趋势,可能会问:"居住在中心区或西区的客户有多少是已婚的?",该问题就是下面这个查询SQL:


      SELECT COUNT(*) FROM CUSTOMER


      WHERE MARITAL_STATUS = 'married' AND REGION IN ('central','west');


      位图索引可以很高效地完成查询,因为只要计算位图中结果为1的数量,如图所示。最后要确认哪些客户符合要求,只要通过位图结果去访问表就可以了。


      status = 'married'     region = 'central'    region = 'west'


      0                          0                   0


      1                          1                   0


      1                          0                   1


      0                 AND(     0           OR      1       )


      0                          1                   0


      1                          1                   0


      0                           0              0


      1                           1              1    ==> 2nd row


      = 1                           1              1    ==> 3rd row


      0                 AND       1            = 0


      0                           1              0


      1                           1              1    ==> last row


      8)位图索引和NULLs


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


      位图索引包含的行有NULL值,和其他类型的索引完全不相同。对null值索引有利于一些类型的SQL语句,如查询包含了聚合函数COUNT。


      例1:


      -------


      SELECT COUNT(*) FROM EMP;


      任何一个位图索引都可以用于该查询,因为表中所有行都被索引,包括那些NULL数据。如果null值未编入索引,优化器只有当,某个字段上有NOT NULL约束时,使用这个字段的索引。


      例2:


      -------


      SELECT COUNT(*) FROM EMP WHERE COMM IS NULL;


      该查询可以通过在COMM上建立一个位图索引来优化。


      例3:


      -------


      SELECT COUNT(*) FROM CUSTOMER WHERE GENDER = 'M' AND STATE != 'CA';


      该查询可以通过GENDER = 'M'的位图减去STATE = 'CA'的位图来得到结果。如果STATE字段包含NULL值(也就是说,该字段上没有NOT NULL约束),那么STATE = 'NULL'的位图也必须从该结果中减去。


      9)表和视图


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


      通过TYPE='BITMAP'条件,可以在USER_INDEXES,ALL_INDEXES,DBA_INDEXES视图中查询到位图索引的信息。


      10)执行计划上的标签


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


      参看:


      Oracle8 Tuning Release 8.0


      Oracle8i Tuning Release 8.1.5


      Oracle9i Database Performance Tuning Guide and Reference Release 1 (9.0.1)


      Oracle9i Database Performance Tuning Guide and Reference Release 2 (9.2)


      Oracle Database Performance Tuning Guide and Reference 10gRelease 1 (10.1)


      Oracle Database Performance Tuning Guide and Reference 10gRelease 2 (10.2)


      Chapter Using EXPLAIN PLAN


      11)使用位图索引的HINT(7.3 - 8.0 - 8.1 - 9.0 - 9.2 - 10.1 - 10.2)


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


      INDEX


      INDEX_COMBINE


      12)初始化参数


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


      <Parameter:CREATE_BITMAP_AREA_SIZE>


      <Parameter:BITMAP_MERGE_AREA_SIZE>


      <Parameter:B_TREE_BITMAP_PLANS>


      <Parameter:V733_PLANS_ENABLED>


    转载地址:http://edu.cnzz.cn/201007/649422ac.shtml

    展开全文
  • 索引:位图索引理解

    万次阅读 多人点赞 2018-08-16 14:29:22
     上面讲了,位图索引适合只有几个固定值的列,如性别、婚姻状况、行政区等等,而身份证号这种类型不适合用位图索引。  此外,位图索引适合静态数据,而不适合索引频繁更新的列。举个例子,有这样一个字段busy,...

    1. 案例

      有张表名为table的表,由三列组成,分别是姓名、性别和婚姻状况,其中性别只有男和女两项,婚姻状况由已婚、未婚、离婚这三项,该表共有100w个记录。现在有这样的查询:     select * from table where Gender=‘男’ and Marital=“未婚”;

    姓名(Name)

    性别(Gender)

    婚姻状况(Marital)

    张三

    已婚

    李四

    已婚

    王五

    未婚

    赵六

    离婚

    孙七

    未婚

    ...

    ...

    ...

     

    1)不使用索引

      不使用索引时,数据库只能一行行扫描所有记录,然后判断该记录是否满足查询条件。

    2)B树索引

      对于性别,可取值的范围只有'男','女',并且男和女可能各站该表的50%的数据,这时添加B树索引还是需要取出一半的数据, 因此完全没有必要。相反,如果某个字段的取值范围很广,几乎没有重复,比如身份证号,此时使用B树索引较为合适。事实上,当取出的行数据占用表中大部分的数据时,即使添加了B树索引,数据库如oracle、mysql也不会使用B树索引,很有可能还是一行行全部扫描。

    2. 位图索引出马

    位图索引创建了之后,生成是位图数据可以这么理解,比如,男女两种,然后一共八条数据,那么就生产两个字符串,一个代表男,一个代表女,字符串长度为数据的总数量,字符串的值:第一位(如果第一条数据是男那么就是1,如果不是就0),第二位,第三位,往后都是这样。由此就生成了长度为总数量,只包含01的字符串,通过这个字符串就能知道第几条数据是男,第几条不是男,同理,另外一条代表女的字符串也一样,是女的就1,不是女的就0。

     

    如果用户查询的列的基数非常的小, 即只有的几个固定值,如性别、婚姻状况、行政区等等。要为这些基数值比较小的列建索引,就需要建立位图索引。

    对于性别这个列,位图索引形成两个向量,男向量为10100...,向量的每一位表示该行是否是男,如果是则位1,否为0,同理,女向量位01011。

    RowId

    1

    2

    3

    4

    5

    ...

    1

    0

    1

    0

    0

     

    0

    1

    0

    1

    1

     

     

      对于婚姻状况这一列,位图索引生成三个向量,已婚为11000...,未婚为00100...,离婚为00010...。

    RowId

    1

    2

    3

    4

    5

    ...

    已婚

    1

    1

    0

    0

    0

     

    未婚

    0

    0

    1

    0

    1

     

    离婚

    0

    0

    0

    1

    0

     

       当我们使用查询语句“select * from table where Gender=‘男’ and Marital=“未婚”;”的时候 首先取出男向量10100...,然后取出未婚向量00100...,将两个向量做and操作,这时生成新向量00100...,可以发现第三位为1,表示该表的第三行数据就是我们需要查询的结果。 

    RowId

    1

    2

    3

    4

    5

    1

    0

    1

    0

    0

    and

     

     

     

     

     

    未婚

    0

    0

    1

    0

    1

    结果

    0

    0

    1

    0

    0

    3.位图索引的适用条件

      上面讲了,位图索引适合只有几个固定值的列,如性别、婚姻状况、行政区等等,而身份证号这种类型不适合用位图索引。

      此外,位图索引适合静态数据,而不适合索引频繁更新的列。举个例子,有这样一个字段busy,记录各个机器的繁忙与否,当机器忙碌时,busy为1,当机器不忙碌时,busy为0。

      这个时候有人会说使用位图索引,因为busy只有两个值。好,我们使用位图索引索引busy字段!假设用户A使用update更新某个机器的busy值,比如update table set table.busy=1 where rowid=100;,但还没有commit,而用户B也使用update更新另一个机器的busy值,update table set table.busy=1 where rowid=12; 这个时候用户B怎么也更新不了,需要等待用户A commit。

      原因:用户A更新了某个机器的busy值为1,会导致所有busy为1的机器的位图向量发生改变,因此数据库会将busy=1的所有行锁定,只有commit之后才解锁。

    展开全文
  • 问题:btree和位图索引之间有什么区别? 我需要了解btree和位图索引之间的结构差异,然后了解在字段上使用b树与位图索引之间的区别。 答:在内部,位图和btree索引有很大的不同,但是在功能上它们是相同的,因为...
  • 传统位图索引技术最大的局限性主要表现在,高基数列的索引尺寸过大从而影响查询性能。所以,从控制索引大小和减少查询响应时间这两个出发点,业内的优化策略一般从以下三个角度切入:分桶(binning)、编码(encoding)...
  • 引言:大家都知道“效率”是数据库中非常重要的一个指标,如何提高效率大家可能都会想起索引,但索引又这么多种,什么场合应该使用什么索引呢?哪种索引可以提高我们的效率,哪种索引可以让我们的效率大大降低(有时...
  • FastBit是位图索引技术的集大成者,是一系列高级位图索引技术的集合。
  • 源头 - 分布式位图索引原语 注意:该项目目前作为概念证明存在。 虽然我信任索引器,但仍有大量性能和可用性问题需要解决。 从好的方面来说,我认为有很多唾手可得的成果。 它代表了我离开计算机所需的几个 hackday...
  • Oracle B树索引和位图索引简介

    千次阅读 2019-01-23 17:43:47
    B 树索引 B 树索引在 Oracle 中是一个通用索引。在创建索引时它就是默认的索引类型。B 树索引可以是一个列的(简单)索引,也可以是多个列的(组合/复合)索引。B 树索引最多可以包括32 列。 在下图的例子中,B 树...
  • Oracle 的位图索引,sql,sql教程,Oracle基础 Oracle的索引主要包含两类:BTree和位图索引。默认情况下大多使用Btree索引,该索引就是通常所见 唯一索引、聚簇索引等等,Btree用在...
  • https://blog.csdn.net/hellojoy/article/details/81740997 位图最好尽量不要使用 在特定的情况下,可以在 性别 婚姻状况等情况下使用。 但在机器人的状态修改时使用就不太合适,因为会对整个位图进行锁定。 ...
  • 创建位图索引

    2016-11-17 23:23:16
    位图索引比较少用,它主要运用于数据量不多,创建在重复性大的字段上面。 以下是创建一个位图索引的过程,前面的主要是添加字段与约束的过程。 ---给表yourtest添加字段并创建位图索引: ---查看表结...
  • 为提高压缩码的利用率,提出一种适用于列存储数据库的压缩位图索引技术。定义反转、合并等操作,将所有计算的输入值与输出值格式化为位向量形式。通过活跃度衡量索引中位向量的复杂度,并对压缩位向量进行直接计算,优化...
  • 一、B-Tree 索引 B-Tree index 也是我们传统上常见所理解的索引。B-tree (balance tree)即平衡树,左右两个分支相对平衡。 B-Tree index Root 为根节点,branch 为分支节点,leaf 到最下面一层称为叶子节点。每个...
  • 最近在项目中遇到一个情况,SQL的where条件设计某一列为人名信息,分布规律较差,筛选率不高,因此选择了位图索引进行创建。语句类似为: create bitmap index "DM_TEST" on "SYSDBA"."TEST("NAME") storage(initial...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,236
精华内容 18,894
关键字:

位图索引