tencent cloud

腾讯云数据仓库 TCHouse-D

产品简介
产品概述
基本概念
集群架构
产品优势
应用场景
购买指南
计费概述
续费说明
到期与欠费说明
退费说明
配置变更计费说明
快速入门
通过控制台使用腾讯云数据仓库 TCHouse-D
通过客户端使用腾讯云数据仓库 TCHouse-D
操作指南
集群操作
监控和告警配置
账户权限管理
数据管理
查询管理
配置管理
节点管理
日志分析
SQL 工作区
开启资源隔离
开发指南
数据表设计
数据导入
数据导出
基础功能
查询优化
生态扩展功能
API 文档
History
Introduction
API Category
Making API Requests
Cluster Operation APIs
Database and Table APIs
Cluster Information Viewing APIs
Hot-Cold Data Layering APIs
Database and Operation Audit APIs
User and Permission APIs
Resource Group Management APIs
Data Types
Error Codes
云上生态
为子账号授予 CAM 策略
查询加速腾讯云 DLC
实践教程
基本功能使用
高级特性使用
资源规格选型及调优建议
命名规范及库表限制
表设计与数据导入
查询调优
建议规避的用法
通过 JDBC 方式公网访问 TCHouse-D
性能测试
TPC-H 性能测试
SSB 性能测试
TPC-DS 性能测试
常见问题
常见操作问题
常见报错
联系我们
词汇表
产品协议
服务等级协议
隐私政策
数据处理和安全协议

Bitmap 索引

PDF
聚焦模式
字号
最后更新时间: 2024-06-27 11:10:40
用户可以通过创建 bitmap index 加速查询。 本文档主要介绍如何创建 bitmap 索引,以及创建 bitmap 索引的一些注意事项和常见问题。

名词解释

bitmap 索引:用位图表示的索引,对索引列的每个键值建立一个位图。是一种快速数据结构,能够加快查询速度。 索引原理示意:


原理介绍

主要针对大量相同值的列而创建(例如:类别,操作员,部门 ID,库房 ID 等),索引块的一个索引行中存储键值和起止 Rowid,以及这些键值的位置编码,位置编码中的每一位表示键值对应的数据行的有无。一个块可能指向的是几十甚至成百上千行数据的位置。
当根据键值查询时,可以根据起始 Rowid 和位图状态,快速定位数据。
当根据键值做 and,or 或 in(x,y,..)查询时,直接用索引的位图进行位运算,快速得出结果行数据。
当执行 select count(xx) 时,可以直接访问索引就快速得出统计数据。

语法

创建和删除本质上是一个 schema change 的作业,具体细节可以参照 Schema Change

创建索引

支持在创建表时就进行 Bitmap 索引指定。
CREATE TABLE create_table_with_bitmap ( l_shipdate date NOT NULL, l_comment varchar(44) NOT NULL, INDEX shipdate_bm_index (l_shipdate) USING BITMAP COMMENT 'shipdate bitmap index' ) ENGINE=OLAP DUPLICATE KEY(l_shipdate) COMMENT 'OLAP' DISTRIBUTED BY HASH(l_shipdate) BUCKETS 96 PROPERTIES ( "replication_allocation" = "tag.location.default: 3", "in_memory" = "false", "storage_format" = "V2", "disable_auto_compaction" = "false" );
也支持对现有的表进行修改增加某一列的 Bitmap 索引,例如在 table1 上为 siteid 创建 Bitmap 索引:
CREATE INDEX [IF NOT EXISTS] index_name ON table1 (siteid) USING BITMAP COMMENT 'balabala';

查看索引

展示指定 table_name 的下索引:
SHOW INDEX FROM example_db.table_name;

删除索引

删除指定 table_name 的下索引:
DROP INDEX [IF EXISTS] index_name ON [db_name.]table_name;




基本原理

腾讯云数据仓库 TChouse-D 使用的是列存储, 在没有索引的情况下,要判断某列F是否与某个值 V 相等,只能遍历一整列所有的数据,才能得到与 V 相等的行号。Bitmap 索引为了避免检索时对所有数据进行遍历,在原来列存数据的基础上,顺序保存列所有的值(有序字典),以及每个值对应的行号。这样在检索时,就可以通过值,快速查找到等于这个值的所有行号。
例如一列数据为[x, x, y, y, y, z, y, x, z, x],一共包含10行,则该列数据的 Bitmap 索引的有序字典为{x, y, z}, x、y、z对应的位图分别为:
x的位图: [0, 1, 7, 9]
y的位图: [2, 3, 4, 6]
z的位图: [5, 8]


注意事项

目前索引命令([show | create | drop] index)仅支持 bitmap 类型的索引。
bitmap 索引仅在单列上创建。
bitmap 索引能够应用在 DuplicateUniq 数据模型的所有列和 Aggregate模型的 key 列上。
bitmap 索引支持的数据类型如下:
TINYINT
SMALLINT
INT
BIGINT
CHAR
VARCHAR
DATE
DATETIME
LARGEINT
DECIMAL
BOOL
bitmap 索引仅在 Segment V2 下生效。当创建 index 时,表的存储格式将默认转换为 V2 格式(查看表的存储格式可通过 show create table table_name 命令)。

bitmap 索引适用场景

适用于低基数的列上,建议在100到100,000之间,如:职业、地市等。重复度过高则对比其他类型索引没有明显优势;重复度过低,则空间效率和性能会大大降低。
特定类型的查询例如 count、or、and 等逻辑操作因为只需要进行位运算。如:通过多个条件组合查询,select count(*) from table where job = '医生' and phonetype = 'iphone' and gender ='男';类似这种场景,如果在每个查询条件列上都建立了 bitmap 索引,则数据库可以进行高效的位运算,精确定位到需要的数据,减少磁盘 IO。并且筛选出的结果集越小,bitmap 索引的优势越明显。
适用于即席查询、多维分析等 OLAP 场景。如果有一张表有100列,用户会使用其中的20个列作为查询条件(任意使用这20个列上的N的列),几乎没有办法创建合适的 b-tree 索引。但是在这些列上创建20个 bitmap 索引,那么所有的查询都可以应用到索引。
Bitmap索引支持等值查询和范围查找,支持= , < , <= ,> ,>= 表达式。

bitmap 索引不适用场景

值重复度低的列,如:身份证号、手机号码等。
重复度过高的列,如:性别,可以建立 bitmap 索引,但不建议单独作为查询条件使用,建议与其他条件共同过滤。
经常需要更新修改的列。

最佳实践

以下基于 TPCH 测试集的 lineitem 表(6亿条记录), 构建 Bitmap 索引和使用。
enter image description here

假设对于 lineitem 表,预期优化以下 sql,优化前耗时约为900ms。
select l_quantity,l_returnflag,l_commitdate from lineitem where l_suppkey = 'xxx';

分析是否适用 Bitmap 索引

查询条件 l_suppkey,此时并不命中前缀索引也没有其他索引。l_suppkey 字段类型为INT ,为可以使用 Bitmap 索引的类型。
查看 l_suppkey 这一列的取值基数,在6亿数据表上,l_suppkey 的取值为100W,取值基数并没有特别高,这里尝试使用 Bitmap 索引进行优化。
enter image description here


创建 Bitmap 和等待索引构建

创建 Bitmap 索引:
create index suppkey_bitmap_index on lineitem(l_suppkey) using bitmap comment 'test';
通过 show alter table column 命令查看索引构建进度:

enter image description here


通过 show create table lineitem 命令查看 lineitem 表存在的索引:
enter image description here


对比优化前后效果

优化后,耗时40ms。
enter image description here

优化前,耗时240ms(这里使用的 lineitem2 表是 lineitem 表的备份,数据量和表结构一致)。
enter image description here


常见问题

select count(*) 对 Bitmap 索引列生效吗?

生效,通过查看对 select count(*) from lineitem where l_suppkey = '388041'; 语句的profile,可以看到 RowsBitmapIndexFiltered 字段帮助过滤了大量数据。
RowsBitmapIndexFiltered: 200.01525M (200015250)

列的取值基数比较大,为什么不适合使用 bitmap 索引?

实测对6亿记录的 lineitem 的 l_partkey 列(2000W取值)进行 bitmap 索引构建。优化前点查耗时600ms,优化后点查耗时为120ms。效率提升了5倍。可见对基数高的列建立索引,查询也能带来效率提升。
但是存储消耗比较大。lineitem 表6亿数据3副本占用约62G存储,对 l_partkey 列构建完 bitmap 索引后,lineitem 表存储涨到95G。理论上,bitmap 索引构建增长的存储,在未压缩情况,为 2000W(取值)* 60000W(行数)bit。
可见对高基数列构建 bitmap 索引,性价比并不高,这个时候更推荐 bloomfilter 索引。


帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈