某系统存储过程执行不过去,通过查询长时间ACTIVE的SESSION定位到如下语句:

UPDATE AAA_BBBBBBBBB_ALM T SET KEY_BS='1111111111'WHERE T.PARTITION_KEY = 'S00000014097'AND T.KEY_BS_BK = 'ASSET_NS-INB-DMD'and SUBSTR(ATTRIBUTE_1,1,6) in ('101101', '101102', '101103','101104');
Plan hash value: 2937027114------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT              |                      |     1 |    74 |     3   (0)| 00:00:01 |
|   1 |  UPDATE                       | AAA_BBBBBBBBB_ALM    |       |       |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID | AAA_BBBBBBBBB_ALM    |     1 |    74 |     3   (0)| 00:00:01 |
|   3 |    BITMAP CONVERSION TO ROWIDS|                      |       |       |            |          |
|*  4 |     BITMAP INDEX SINGLE VALUE | AAA_BBBBBBBBB_ALM_B1 |       |       |            |          |
------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - filter("T"."KEY_BS_BK"='ASSET_NS-INB-DMD' AND (SUBSTR("ATTRIBUTE_1",1,6)='101101' OR SUBSTR("ATTRIBUTE_1",1,6)='101102' OR SUBSTR("ATTRIBUTE_1",1,6)='101103' OR SUBSTR("ATTRIBUTE_1",1,6)='101104'))4 - access("T"."PARTITION_KEY"='S00000014097')

通过执行计划可以得出,BITMAP INDEX SINGLE VALUE 先通过键值筛选,然后BITMAP CONVERSION TO ROWIDS转换为rowid,再通过ROWID去回表TABLE ACCESS BY INDEX ROWID,这个过程和普通的索引扫描类似,只是多了一个BITMAP CONVERSION TO ROWIDS的操作!查一下PARTITION_KEY字段的选择性

SELECT PARTITION_KEY,COUNT(*) FROM AAA_BBBBBBBBB_ALM GROUP BY PARTITION_KEY;
1    S00000014097    796083

呵呵了!整个表distinct值就一个,BITMAP INDEX SINGLE VALUE筛选根本没起作用,索引会取出所有行的ROWID,然后回表的时候回了读取了表所有的数据块,而且是单块读!

下面的图片显示了表上面所有的索引信息,而且都是位图索引。

.

这里我们详细说一下位图索引的原理和使用场景:

上图中 一个表上面建立了10个bitmap索引,如果是b-tree索引,一般不会允许建如此多,维护和存储花费的代价将很大。

而位图索引,则没有问题,这和他的存储方式有关。比如一个表有1000w 行,性别列 男 999w 女1w

如果是b-tree索引,存储的方式是这样的

男 ,ROWID

.....

男,ROWID   ->第999w行

女,ROWID

.....

女,ROWID ->第1w行

索引的叶子节点里面存储的数据行数是1000w行。

如果是bitmap索引,存储的方式是这样的,把 男 女 分别用1,0表示

男 ,ROWID 1条  1010001......
女 ,ROWID 1条  0101110......    男人 女人 存2条其他地方 用1 0 代替

可见DISTINCT值越多,行数就越多!这也是为什么位图索引最好建在基数低的列

如果一个表上面建多个位图索引比如 婚姻状态列(已婚、未婚、离异),级别(OCA、OCP、OCM) ........这样一个表上面有多个位图索引,存储方式如下:

对于性别这个列,位图索引形成两个向量,男向量为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

对于级别这一列,同样生成三个向量,OCA为11000...,OCP为00100...,OCM为00010...。

RowId

1

2

3

4

5

...

OCA

1

1

0

0

0

OCP

0

0

1

0

1

OCM

0

0

0

1

0

在这个案例中位图索引只使用了一个条件"T"."PARTITION_KEY"='S00000014097',这个条件BITMAP INDEX SINGLE VALUE筛选的结果就是 向量11111111111....11111再通过对应的位置,把向量转成ROWID(BITMAP CONVERSION TO ROWIDS)。所以切记 不要把位图索引当做B树索引来使用。

位图索引的使用场景:通常是SQL语句必须有多个含有位图索引字段的过滤条件,CBO去解析时,先通过这个条件再位图内部做逻辑运算(与 或 非)。比如:select * from table where 性别='男' and 婚姻状况='未婚',首先取出男向量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

 

我们得到的向量00100,表示第三个ROWID是我们需要,通过位图转换出ROWID的值即可!如果条件里面再加上AND 级别='OCM',可以进一步缩小行数,缩小转换出的ROWID个数。

总结一下:位图索引的适用场景是表上有多个选择性不好的列,而对于这个表的查询语句条件里多次使用这些列,就可以通过在这些列上面建位图索引的方式来提高查询效率(注:OLTP系统严禁使用位图索引)

根据上面的分析,需要优化的SQL完全符合使用位图索引的条件。条件列里面有4个逻辑或3个逻辑与,只是SQL没有按照位图的原理去走逻辑或和逻辑与,而是把位图索引当成普通的B树索引来用。这时候我们需要使用HINT强制让位图索引进行位运算

The INDEX_COMBINE hint instructs the optimizer to use a bitmap access path for the table. If indexspec is omitted from the INDEX_COMBINE hint, then the optimizer uses whatever Boolean combination of indexes has the best cost estimate for the table. If you specify indexspec, then the optimizer tries to use some Boolean combination of the specified indexes.

使用HINT后的执行计划如下:
UPDATE /*+ index_combine(t AAA_BBBBBBBBB_ALM_B1 AAA_BBBBBBBBB_ALM_B2 AAA_BBBBBBBBB_ALM_B7) */AAA_BBBBBBBBB_ALM T SET KEY_BS='1111111111'WHERE T.PARTITION_KEY = 'S00000014097'AND T.KEY_BS_BK = 'ASSET_NS-INB-DMD'and SUBSTR(ATTRIBUTE_1,1,6) in ('101101', '101102', '101103','101104');              Plan hash value: 82554262-------------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT               |                      |     1 |    74 |    18   (0)| 00:00:01 |
|   1 |  UPDATE                        | AAA_BBBBBBBBB_ALM    |       |       |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID  | AAA_BBBBBBBBB_ALM    |     1 |    74 |    18   (0)| 00:00:01 |
|   3 |    BITMAP CONVERSION TO ROWIDS |                      |       |       |            |          |
|   4 |     BITMAP AND                 |                      |       |       |            |          |
|*  5 |      BITMAP INDEX SINGLE VALUE | AAA_BBBBBBBBB_ALM_B1 |       |       |            |          |
|*  6 |      BITMAP INDEX SINGLE VALUE | AAA_BBBBBBBBB_ALM_B2 |       |       |            |          |
|   7 |      BITMAP OR                 |                      |       |       |            |          |
|*  8 |       BITMAP INDEX SINGLE VALUE| AAA_BBBBBBBBB_ALM_B7 |       |       |            |          |
|*  9 |       BITMAP INDEX SINGLE VALUE| AAA_BBBBBBBBB_ALM_B7 |       |       |            |          |
|* 10 |       BITMAP INDEX SINGLE VALUE| AAA_BBBBBBBBB_ALM_B7 |       |       |            |          |
|* 11 |       BITMAP INDEX SINGLE VALUE| AAA_BBBBBBBBB_ALM_B7 |       |       |            |          |
-------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------5 - access("T"."PARTITION_KEY"='S00000014097')6 - access("T"."KEY_BS_BK"='ASSET_NS-INB-DMD')8 - access(SUBSTR("ATTRIBUTE_1",1,6)='101101')9 - access(SUBSTR("ATTRIBUTE_1",1,6)='101102')10 - access(SUBSTR("ATTRIBUTE_1",1,6)='101103')11 - access(SUBSTR("ATTRIBUTE_1",1,6)='101104')

bitmap index的优化案例相关推荐

  1. sql的不等于条件优化_SQL优化案例(2):OR条件优化

    随后上一篇文章< SQL优化案例(1):隐式转换>的介绍,此处内容围绕OR的优化展开. 在MySQL中,同样的查询条件,如果变换OR在SQL语句中的位置,那么查询的结果也会有差异,在多个复 ...

  2. 优化案例 | CASE WHEN进行SQL改写优化

    导读 今天给大家分享一个通过SQL改写而独辟蹊径的SQL优化案例 待优化场景 发现SLOW QUERY LOG中有下面这样一条记录: ... # Query_time: 59.503827 Lock_ ...

  3. 崔华 oracle简历,2013数据库大会:崔华-基于Oracle的SQL优化案例分析

    2013数据库大会:崔华-基于Oracle的SQL优化案例分析 崔华的新书即将出版,其数据库大会上的演讲也非常精彩,他的新书十分值得期待. 2013年中国数据库技术大会第二天的"Oracle ...

  4. Mysql之索引优化案例

    Mysql之索引优化案例 1.单表简单案例 1.1创建表 1.2 问题: 1.3 解决:新建索引 1.4 再次执行 2.双表简单案例 2.1创建表并插入数据 2.2 由于是LEFT JOIN,所以左表 ...

  5. sql 从ip列表中查询ip段_IP地址段查询深度优化案例

    作者介绍 陈华军,苏宁IT总部架构专家,PostgreSQL及MySQL产品技术负责人,PostgreSQL中文社区核心成员. 问题 某日,研发的小伙伴扔过来一个SQL希望帮忙优化. select n ...

  6. Android 性能优化案例

    2019独角兽企业重金招聘Python工程师标准>>>         之前看到一篇关于优化Android性能的文章,写的很不错.但由于一直没有使用过,最近恰好优化Performan ...

  7. mysql sum 慢_故障分析 | MySQL 优化案例 - select count(*)

    作者:xuty 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源. 本文关键字:count.SQL.二级索引 一.故事背景 项目组联系我说是有一张 50 ...

  8. mysql bitmap index_位图索引:原理(BitMap index)

    位图(BitMap)索引 前段时间听同事分享,偶尔讲起Oracle数据库的位图索引,顿时大感兴趣.说来惭愧,在这之前对位图索引一无所知,因此趁此机会写篇博文介绍下位图索引. 1. 案例 有张表名为ta ...

  9. 突破性能瓶颈!ElasticSearch百亿级数据检索优化案例

    一.前言 本文中的数据平台已迭代三个版本,从头开始遇到很多常见的难题,终于有片段时间整理一些已完善的文档,在此分享以供所需朋友的.实现参考,少走些弯路,在此篇幅中偏重于ES的优化,目前生产已存储百亿数 ...

最新文章

  1. Yann LeCun 怒喷 Sophia:这就是彻头彻尾的骗局
  2. 《算法进阶指南》最小生成树剩余题目
  3. Java的知识点32——Mysql的简单使用
  4. spring 的IoC的个人理解
  5. ds证据理论python实现_你好,Julia!再见,Python!
  6. java 图片导出_java导出含图片的word
  7. vscode 支持 markdown 流程图
  8. python基础编码规范_Python语言的基本语法和编码规范.doc
  9. java批量执行多条Sql语句
  10. mysql主从复制超简单_MYSQL 主从复制---简单易学
  11. .Net向Page和UpdatePanel输出JS
  12. hal linux 手册_Linux服务之:haldaemon服务 | 旺旺知识库
  13. 基于python的三维射线追踪库-ttcrpy详解(1)
  14. cipher加密解密
  15. Java可以hook微信吗,Hook实现Android 微信、陌陌 、探探位置模拟(附源码下载)
  16. Postman批量参数化测试
  17. gmai邮箱怎么注册啊
  18. Python中记录程序运行时间
  19. 网页模板设计中5种常见的设计版式类型介绍
  20. Matlab的基本使用方法

热门文章

  1. Diagonal distance in 23 dimensions
  2. 电子沙盘开发教程 数字沙盘GIS大数据人工智能
  3. Django模板系统(十分 非常详细)
  4. 禁用计算机账户控制,win8系统禁止弹出用户账户控制窗口的方法
  5. Java JDK 1.8 下载及其版本说明 8u202(最后一个免费版)
  6. Linux安装配置JavaJDK
  7. Where Can Machine Learning Help Robotic State Estimation 机器学习在机器人状态估计的应用
  8. Jade_Primer---first program--JADE OPTIONS
  9. java urlencoder 特殊_java URLEncoder 中特殊处理
  10. uni-app 封装js方、页面的生命周期、数据双向绑定、封装组件