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

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

本文内容

  • 比较索引
  • 步骤 3A(TEST_NORMAL 表 EMPNO 列创建 Bitmap 索引,执行范围查询)
  • 步骤 3B(TEST_NORMAL 表 EMPNO 列创建 B-tree 索引,执行范围查询)
  • 步骤 4A(TEST_RANDOM 表 EMPNO 列创建 Bitmap 索引,执行范围查询)
  • 步骤 4B(TEST_RANDOM 表 EMPNO 列创建 B-tree 索引,执行范围查询)

步骤 3A(在 TEST_NORMAL)


该步骤创建 Bitmap 索引(同步骤 1A)。我们已经知道索引大小(28MB)及其聚类系数(等于表的行数)。现在执行一些范围谓词谓词查询。

SQL> drop index normal_empno_idx;
 
索引已删除。
 
SQL> create Bitmap index normal_empno_bmx on test_normal(empno);
 
索引已创建。
 
SQL> analyze table test_normal compute statistics for table for all indexes for
all columns;
 
表已分析。
 
SQL>

SQL> set autot traceonly
SQL> select * from test_normal where empno between &range1 and &range2;
输入 range1 的值:  1
输入 range2 的值:  2300
原值    1: select * from test_normal where empno between &range1 and &range2
新值    1: select * from test_normal where empno between 1 and 2300
 
已选择2300行。
 
 
执行计划
----------------------------------------------------------
Plan hash value: 641040856
 
-------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                  |  2299 | 85063 |   417  (0)| 00:00:06 |
|   1 |  TABLE ACCESS BY INDEX ROWID | TEST_NORMAL      |  2299 | 85063 |   417  (0)| 00:00:06 |
|   2 |   BITMAP CONVERSION TO ROWIDS|                  |       |       |           |          |
|*  3 |    BITMAP INDEX RANGE SCAN   | NORMAL_EMPNO_BMX |       |       |           |          |
-------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("EMPNO">=1 AND "EMPNO"<=2300)
 
 
统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        331  consistent gets
          0  physical reads
          0  redo size
     130220  bytes sent via SQL*Net to client
       2202  bytes received via SQL*Net from client
        155  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       2300  rows processed
 
SQL>

步骤 3B(在 TEST_NORMAL)


该步骤对 TEST_NORMAL 表 EMPNO 列使用 B-tree 索引,执行范围谓词查询。

SQL> set autot off
SQL> drop index normal_empno_bmx;
 
索引已删除。
 
SQL> create index normal_empno_idx on test_normal(empno);
 
索引已创建。
 
SQL> analyze table test_normal compute statistics for table for all indexes for
all indexed columns;
 
表已分析。
 
SQL>

SQL> set autot traceonly
SQL> select * from test_normal where empno between &range1 and &range2;
输入 range1 的值:  1
输入 range2 的值:  2300
原值    1: select * from test_normal where empno between &range1 and &range2
新值    1: select * from test_normal where empno between 1 and 2300
 
已选择2300行。
 
 
执行计划
----------------------------------------------------------
Plan hash value: 1781697849
 
------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                  |  2299 | 85063 |    23 (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST_NORMAL      |  2299 | 85063 |    23 (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | NORMAL_EMPNO_IDX |  2299 |       |     8 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("EMPNO">=1 AND "EMPNO"<=2300)
 
 
统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        329  consistent gets
          0  physical reads
          0  redo size
     130220  bytes sent via SQL*Net to client
       2202  bytes received via SQL*Net from client
        155  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       2300  rows processed
 
SQL>

当输入不同范围查询时,结果如下所示:

表 4 TEST_NORMAL 表 EMPNO 列利用 Bitmap 和 B-tree 索引执行范围查询比较

Bitmap B-tree
Consistent Reads Physical Reads EMPNO (Range) Consistent Reads Physical Reads

331

0

1-2300

329

0

285

0

8-1980

283

0

346

19

1850-4250

344

16

427

31

28888-31850

424

28

371

27

82900-85478

367

23

2157

149

984888-1000000

2139

35

如上表所示,两个索引的 consistent gets 和 physical reads 值很接近。表最后一行查询范围 (984888-1000000) 返回了将近 15000 行。因此,当我们要求一个全表扫描时(指定优化器提示为 /*+ full(test_normal) */ ),consistent read 和 physical read 值分别为 7239 和 5663。

3A 和 3B 的演示,在 TEST_NORMAL 表执行范围查询时,优化器使用了 EMPNO 列上的相应索引,逻辑 IO 和物理 IO 只是稍有差异。

步骤 4A(在 TEST_RANDOM)


该步骤在 TEST_RANDOM 表 EMPNO 列使用 Bitmap 索引进行范围查询,检查 consistent gets 和 physical reads 值。这里,你会看到聚类系数的影响。

SQL> drop index random_empno_idx;
 
索引已删除。
 
SQL> create Bitmap index random_empno_bmx on test_random(empno);
 
索引已创建。
 
SQL> analyze table test_random compute statistics for table for all indexes for
all indexed columns;
 
表已分析。
 
SQL>

SQL> set autot traceonly
SQL> select * from test_random where empno between &range1 and &range2;
输入 range1 的值:  1
输入 range2 的值:  2300
原值    1: select * from test_random where empno between &range1 and &range2
新值    1: select * from test_random where empno between 1 and 2300
 
已选择2300行。
 
 
执行计划
----------------------------------------------------------
Plan hash value: 4105816815
 
-------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                  |  2299 | 89661 |   418  (1)| 00:00:06 |
|   1 |  TABLE ACCESS BY INDEX ROWID | TEST_RANDOM      |  2299 | 89661 |   418  (1)| 00:00:06 |
|   2 |   BITMAP CONVERSION TO ROWIDS|                  |       |       |           |          |
|*  3 |    BITMAP INDEX RANGE SCAN   | RANDOM_EMPNO_BMX |       |       |           |          |
-------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("EMPNO">=1 AND "EMPNO"<=2300)
 
 
统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       2463  consistent gets
          0  physical reads
          0  redo size
     130220  bytes sent via SQL*Net to client
       2202  bytes received via SQL*Net from client
        155  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       2300  rows processed
 
SQL>

步骤 4B(在 TEST_RANDOM)


该步骤在 TEST_RANDOM 表 EMPNO 列使用 B-tree 索引进行范围查询。回忆一下索引的聚类系数非常接近表中行数(因此,不会很有效)。下面看看优化器是如何说的:

SQL> drop index random_empno_bmx;
 
索引已删除。
 
SQL> create index random_empno_idx on test_random(empno);
 
索引已创建。
 
SQL> analyze table test_random compute statistics for table for all indexes for
  2  all indexed columns;
 
表已分析。
 
SQL>

SQL> select * from test_random where empno between &range1 and &range2;
输入 range1 的值:  1
输入 range2 的值:  2300
原值    1: select * from test_random where empno between &range1 and &range2
新值    1: select * from test_random where empno between 1 and 2300
 
已选择2300行。
 
 
执行计划
----------------------------------------------------------
Plan hash value: 2650160170
 
---------------------------------------------------------------------------------
| Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)| Time
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |             |  2299 | 89661 |  1740   (1)| 00:00:21|
|*  1 |  TABLE ACCESS FULL| TEST_RANDOM |  2299 | 89661 |  1740   (1)| 00:00:21|
---------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("EMPNO"<=2300 AND "EMPNO">=1)
 
 
统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       6412  consistent gets
          0  physical reads
          0  redo size
     121076  bytes sent via SQL*Net to client
       2202  bytes received via SQL*Net from client
        155  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       2300  rows processed
 
SQL>

由于聚类系数的原因,优化器选择了全表扫描,而不是索引:

Bitmap B-tree
Consistent Reads Physical Reads EMPNO (Range) Consistent Reads Physical Reads

2463

1200

1-2300

6415

4910

2114

31

8-1980

6389

4910

2572

1135

1850-4250

6418

4909

3173

1620

28888-31850

6456

4909

2762

1358

82900-85478

6431

4909

7254

3329

984888-1000000

7254

4909

只有表最后一行,对 Bitmap 索引,优化器选择了全表扫描,而对于所有的范围查询,对 B-tree 索引,优化器选择全表扫描。这种差异是由于簇因素:当使用 bitmap 索引产生执行计划时,优化器不考虑聚类系数的值,而对 B-tree 索引,则考虑。在这个场景,Bitmap 索引比 B-tree 索引更有效率。

4A 和 4B 的演示,在 TEST_RANDOM 表执行范围查询时,当索引时 Bitmap 索引时,优化器使用了;可当索引时 B-tree 索引时,优化器没有使用,而是进行了全表扫描,逻辑 IO 和物理 IO 自然也就差异很大。

原因就在于 TEST_NORMAL 表是已组织的,而 TEST_RANDOM 表示无组织的。这就好像数据结构中的查找算法或排序算法,如果当前数组是已有序的,查找和排序会快很多。

下面步骤会揭示关于索引更有趣的事实。

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

  1. 位图索引和B tree索引的区别

    (1).与索引相关视图 查询DBA_INDEXES视图可得到表中所有索引的列表:访问USER_IND_COLUMNS视图可得到一个给定表中被索引的特定列. (2).组合索引概念 当某个索引包含有多个已 ...

  2. MySQL索引(B+Tree 索引、哈希索引、全文索引、 空间数据索引)、索引优化、优点、使用场景

    1. MySQL 索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现. 1.1 B+Tree 索引 是大多数 MySQL 存储引擎的默认索引类型. 因为不再需要 ...

  3. oracle索引 oracle索引结构 oracle索引使用 B*Tree索引

    在进行数据查询的时候如果碰到大量数据集中的少量数据查询问题,可以通过在查询字段上新增索引提高查询速度 如果查询的结果集是大批量数据,那么就没必要使用索引了. 索引结构 举个例子:表A 列 a, b, ...

  4. mysql explain详解_数据库mysql(1)——B+TREE索引原理

    一.B+Tree索引详解 1.什么是索引? 索引:加速查询的数据结构. 2.索引常见数据结构: #1.顺序查找: 最基本的查询算法-复杂度O(n),大数据量此算法效率糟糕. #2.二叉树查找(bina ...

  5. 初入了解MySQL储存引擎和B+Tree索引

    InnoDB存储引擎 从mysql5.5.8开始,InnoDB是默认的存储引擎.在InnoDB中存在着缓冲管理,通过缓冲池,将索引和表数据全部缓存起来,加快查询的速度. 由 .frm文件.表空间(分为 ...

  6. Oracle Database 中 B*Tree 索引内部维护

    最近一周在复习索引相关的东西,除了回顾concept,还在MOS上看到了一篇比较好的文档.分享给大家. 文档编号:[ID 30405.1] This article is only concerned ...

  7. mysql单列索引和多列索引_浅谈MySQL索引优化

    索引基础知识总结及常见索引优化手段 一.索引简介 什么是索引? MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构. 可以简单理解为"排好序的快速查找数据 ...

  8. MySQL第10天:MySQL索引优化分析之索引介绍

    MySQL索引优化分析之索引简介 1.索引是什么? 2.索引优势.劣势 3.索引分类.基本语法 4.索引结构 5.哪些情况需要创建索引? 6.哪些情况不需要创建索引? ---------------- ...

  9. MySQL的索引(普通索引、唯一索引,主键索引、组合索引、全文索引、空间索引)相关操作

    目录 索引介绍 Hash索引和B+tree索引的区别 应用场景 索引分类 普通索引 创建单列索引--普通索引(3种语法) 查看数据库中的索引 查看数据表中的索引 删除索引 唯一索引 主键索引 组合索引 ...

  10. 加载八叉树索引文件_这篇 MySQL 索引和 B+Tree 讲的太通俗易懂!

    正确的创建合适的索引,是提升数据库查询性能的基础.在正式讲解之前,对后面举例中使用的表结构先简单看一下: create table user (id bigint not null comment ' ...

最新文章

  1. Java培训都学什么
  2. VMware workstation 7.1 安装错误提示1021解决方法
  3. JavaScript多文件下载
  4. 网站被写入恶意代码的主要原因及防范策略
  5. 华为p10plus能用鸿蒙吗,华为P10/P10 Plus对比评测:自家兄弟大对决
  6. 3650m5设置u盘启动_联想和华硕笔记本重装系统时新BIOS无法设置u盘启动怎么办
  7. (09)FPGA时序分析模型
  8. Struts2工作流程
  9. 屏幕录像专家 7.5下载+注册机
  10. 明翰英语教学系列之形容词与副词篇V0.1(持续更新)
  11. 基于深度学习的图像篡改识别
  12. python与会计学_会计有必要学python吗?
  13. uniapp 生成html5_uni-app 登录(h5+ app 篇)
  14. PTA Python函数题 7-1 模拟乒乓球比赛 (20 分)
  15. 笑cry!在镜子面前,沉稳暖心的金毛同学也会瞬间化身逗比!
  16. 积分球测试软件无法创建新文档,积分球测试光通量不准确的解决方案
  17. Andriod Studio虚拟机启动失败解决方案
  18. vmlinux 反汇编_看vmlinux的符号信息
  19. 有了它,你的照片能“屏蔽”人脸识别算法
  20. web mysql报表工具_新一代Java web报表工具—Smartbi电子表格的优势

热门文章

  1. 2016-11-17试题解题报告
  2. centos6安装配置
  3. 浅谈 underscore 内部方法 group 的设计原理
  4. EasyUI框架入门学习
  5. Vs2008不能调试的问题
  6. NSIS 打包 win7 中无法删除快捷方式
  7. 多个Finder方法的外部内容类型
  8. 使用脚本将数据从辅助数据源传送到 InfoPath 域
  9. jsp页面截取字符串,显示指定长度
  10. vuex实践之路——笔记本应用(三)