Oracle位图索引技术

晚上好!

我们正在启动新课程“关系数据库管理系统”的第二个流,我们对第一次运行的结果做了一些完成:码头工人和各种“文件改进”都需要MySQL和Postgres集群上的其他类。 因此,请期待公开课程(其中一些旧主题已被淘汰)和有趣的材料。 今天,我们深入研究Oracle的技术。

走吧

Oracle位图索引与标准B树索引非常不同。 在位图结构中,将为索引表中的每一行创建一个带有一列的二维数组。 每列代表位图索引中的单独值。 此二维数组显示每个索引值乘以该表中的行数。

Oracle将位图(具有行检索速度)解压缩到RAM数据缓冲区中,以便快速扫描匹配值。 这些匹配的值作为行ID列表传递给Oracle,并且行ID值可以直接访问所需的信息。



当一个表包含多个位图索引时,位图索引的一个特殊优势就体现出来了。 每列的功率可能很低。 创建多个位图索引提供了一种非常强大的方法,可以快速响应复杂的SQL查询。



使用位图池化方法,当处理具有少量元素的多列时,Oracle将响应时间减少了不到一秒钟。

还应注意有关Oracle位图索引最大值的重要说明

例如,假设有一个包含大量低功率列的汽车数据库:car_color,car_make,car_model和car_year。 每列包含少于100个不同的值,在这样的2000万辆汽车的数据库中,b树索引将完全无用。

但是,将这些索引合并到查询中可以提供较高的响应时间,这比读取基本表中2000万行中每行的传统方法要快得多。 例如,假设我们要查找1981年制造的旧蓝色丰田花冠:

select license_plat_nbr from vehicle where color = "blue" and make = "toyota" and year = 1981; 

为了处理该查询,Oracle使用了一种特殊的优化方法,称为合并位图索引。 在这种方法中,每个行ID列表(简称RID)是使用位图分别形成的,并且使用特殊的合并过程来比较RID列表并搜索重叠值。

随着不同值数量的增加,位图的大小呈指数增长。 因此,具有100个值的索引可以比具有1000个不同列值的位图索引快1000倍。

值得记住的是,位图索引仅适用于静态表和实例化视图,这些表在夜间更新并在批量加载行后重新构建。 如果您的表中每秒发生几DML,请在实现位图索引时务必小心!

  • 1至7个不同的键值-具有低功耗位图索引的查询非常快;
  • 8-100个不同的键值-随着不同值的数量增加,生产率成比例地下降;
  • 100-10,000个不同的值-具有100多个不同的值,位图索引变得巨大,并且SQL性能迅速下降。
  • 超过10,000个不同的键值-在这个阶段,性能比具有100个不同值的索引要低十倍。

Oracle位图索引是Oracle的一项非常强大的功能,但是有一些陷阱!

在以下情况下,您将需要使用位图索引:

  1. table列是轻量级的-对于DRAFT手册,请考虑具有小于100个不同值的任何索引的位图:

     select region, count(*) from sales group by region; 
  2. LOW DML表-插入/更新/删除使用率应较低。 更新位图索引需要大量资源,因此它们更适合每晚使用只读表和批更新表。
  3. 多列-您的SQL查询在Where语句中引用基数较低的多个字段。 位图索引的存在将有助于Oracle优化器的工作,该优化器将基于成本(简称CBO(基于成本的优化器))进行估算。

对Oracle位图索引进行故障排除

最常见的位图索引实现问题包括:

  • 小表-如果CBO太小,则可能需要全表扫描!
  • 错误的统计信息-确保创建后立即使用dbms_stats分析位图:

 CREATE BITMAP INDEX emp_bitmap_idx ON index_demo (gender); exec dbms_stats.gather_index_stats(OWNNAME=>'SCOTT', INDNAME=>'EMP_BITMAP_IDX'); 

  • 工具提示测试-要使用新的位图索引,请使用Oracle INDEX工具提示:

 select /*+ index(emp emp_bitmap_idx) */ count(*) from emp, dept where emp.deptno = dept.deptno; 

我们正在这里等待问题和评论,或参加我们的新公开课

Source: https://habr.com/ru/post/zh-CN433090/


All Articles