• Bitmap 索引 vs. Btree 索引:如何选择以及何时使用?——45


    ——理解适当使用每个索引对性能的影响

    Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——1-5

    Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——2-5

    Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——3-5

    Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——4-5

    Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——5-5

    本文内容

    • 步骤 6(添加一个 GENDER 列)

    步骤 6(添加一个 GENDER 列)


    在一个低基数列执行测试前,向表添加一个 GENDER 列,并基于某个条件用 M、F、null 值来更新。

    SQL> alter table test_normal add GENDER varchar2(1);
     
    表已更改。
     
    SQL>

    用下面匿名过程更新 GENDER 列的值,之后看看列值如何分布:

    DECLARE
      v_empno test_normal.empno%type;
      CURSOR c IS
        SELECT empno FROM test_normal;
    BEGIN
      OPEN c;
      LOOP
        FETCH c
          INTO v_empno;
        exit when c%notfound;
        IF dbms_random.random MOD 3 = 1 THEN
          UPDATE test_normal set gender = 'M' WHERE empno = v_empno;
        ELSIF dbms_random.random mod 3 = 2 THEN
          UPDATE test_normal set gender = 'F' WHERE empno = v_empno;
        ELSIF dbms_random.random mod 3 = 0 THEN
          UPDATE test_normal set gender = null WHERE empno = v_empno;
        END IF;
        commit;
      END LOOP;
      CLOSE c;
    END;
    SQL> select GENDER, count(*) from test_normal group by GENDER;
     
    GENDER       COUNT(*)
    ---------- ----------
                   385961
    M              320767
    F              293272
     
    SQL>

    该列上的 Bitmap 索引大小约在 620KB 左右,如下所示:

    SQL> create bitmap index normal_GENDER_bmx on test_normal(GENDER);
     
    索引已创建。
     
    SQL> select substr(segment_name,1,30) segment_name, bytes/1024/1024 "Size in MB"
      2  from user_segments
      3  where segment_name in ('TEST_NORMAL','NORMAL_GENDER_BMX');
     
    SEGMENT_NAME                                                 Size in MB
    ------------------------------------------------------------ ----------
    NORMAL_GENDER_BMX                                                  .625
    TEST_NORMAL                                                          50
     
    SQL>

    相比,该列上的 B-tree 索引为 9MB,比 Bitmap 索引大很多。

    SQL> drop index normal_gender_bmx;
     
    索引已删除。
     
    SQL> create index normal_gender_idx on test_normal(gender);
     
    索引已创建。
     
    SQL> select substr(segment_name,1,30) segment_name, bytes/1024/1024 "Size in MB"
     
      2  from user_segments
      3  where segment_name in ('TEST_NORMAL','NORMAL_GENDER_IDX');
     
    SEGMENT_NAME                                                 Size in MB
    ------------------------------------------------------------ ----------
    NORMAL_GENDER_IDX                                                     9
    TEST_NORMAL                                                          50
     
    SQL>

    现在,若执行一个等值谓词查询,那么优化器将不使用索引,Bitmap 索引或 B-tree 索引。而是执行一个全表扫描。

    SQL> select * from test_normal where GENDER is null;
     
    已选择385961行。
     
     
    执行计划
    ----------------------------------------------------------
    Plan hash value: 512490529
     
    ---------------------------------------------------------------------------------
    | Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)| Time|
    ---------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |             |  1000K|    37M|  1725   (2)| 00:00:21|
    |*  1 |  TABLE ACCESS FULL| TEST_NORMAL |  1000K|    37M|  1725   (2)| 00:00:21|
    ---------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("GENDER" IS NULL)
     
     
    统计信息
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
          31825  consistent gets
              0  physical reads
              0  redo size
       22065645  bytes sent via SQL*Net to client
         283550  bytes received via SQL*Net from client
          25732  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
         385961  rows processed
     
    SQL>
    SQL> select * from test_normal where GENDER='M';
     
    已选择320767行。
     
     
    执行计划
    ----------------------------------------------------------
    Plan hash value: 654360527
     
    -------------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                   |     1 |    39 |     2  (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST_NORMAL       |     1 |    39 |     2  (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | NORMAL_GENDER_IDX |     1 |       |     2  (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("GENDER"='M')
     
     
    统计信息
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
          49138  consistent gets
              0  physical reads
              0  redo size
       19044637  bytes sent via SQL*Net to client
         235744  bytes received via SQL*Net from client
          21386  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
         320767  rows processed
     
    SQL>
    SQL> select * from test_normal where GENDER='F';
     
    已选择293272行。
     
     
    执行计划
    ----------------------------------------------------------
    Plan hash value: 654360527
     
    -------------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                   |     1 |    39 |     2  (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST_NORMAL       |     1 |    39 |     2  (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | NORMAL_GENDER_IDX |     1 |       |     2  (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("GENDER"='F')
     
     
    统计信息
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
          45430  consistent gets
              0  physical reads
              0  redo size
       17412131  bytes sent via SQL*Net to client
         215581  bytes received via SQL*Net from client
          19553  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
         293272  rows processed
     
    SQL>

    表 8 Bitmap 索引在 TEST_NORMAL 表 EMPNO、SAL 和 GENDER 列的统计信息 

      EMPNO SAL GENDER
    基数程度   高   一般   低
    size   28MB   4MB   625KB

    基数越低,Bitmap 索引越小。

    表 9 B-tree 索引在 TEST_NORMAL 表 EMPNO、SAL 和 GENDER 列的统计信息

      EMPNO SAL GENDER
    基数程度   高   一般   低
    size   18MB   17MB   9MB
  • 相关阅读:
    当前读与快照读
    Oracle临时表(Temporary Table)
    DG一主两备搭建
    配置dg broker
    源码编译安装PostgreSQL(pg12)
    Troubleshooting ORA-00600 [ORA_NPI_ERROR] ORA-00600: internal error code [kffilCreate01]
    mysql多实例配置(多配置文件)
    mysql多实例配置(单配置文件)
    Fixed Views Definitions in Oracle Database 11.2
    charles 禁用Cookies /Block Cookies Settings
  • 原文地址:https://www.cnblogs.com/liuning8023/p/2765426.html
Copyright © 2020-2023  润新知