索引
索引用于帮助快速过滤或查找数据。
目前Doris支持两类索引:内建的智能索引,包括前缀索引和ZoneMap索引;用户创建的二级索引,包括Bloom Filter索引和Bitmap索引。
前缀索引
本质上,Doris的数据存储在类似SSTable(Sorted String Table)的数据结构中。该结构是一种有序的数据结构,可以按照指定的列进行排序存储。在这种数据结构上,以排序列作为条件查找,会非常高效。
而前缀索引,是在排序的基础上实现的一种根据给定前缀列,快速查询数据的索引方式。
前缀索引是将一行数据的前36个自己作为这行数据的前缀索引,并且当遇到VARCHAR类型时,前缀索引直接截断。
举例说明:
- 下表的前缀索引为user_id(8 Bytes) + age(4 Bytes) + message(prefix 20 Bytes)
ColumnName | Type |
---|---|
user_id | BIGINT |
age | INT |
message | VARCHAR(100) |
max_dwell_time | DATETIME |
- 下表的前缀索引为user_name(20 Bytes),即使没有达到 36 个字节,因为遇到 VARCHAR,所以直接截断,不再往后继续
ColumnName | Type |
---|---|
user_name | VARCHAR(20) |
age | INT |
message | VARCHAR(100) |
当我们的查询条件,是前缀索引的前缀时,可以极大的加快查询速度。比如在第一个例子中,我们执行如下查询:
SELECT * FROM table WHERE user_id=1829239 and age=20;
该查询的效率会远高于如下查询:
SELECT * FROM table WHERE age=20;
所以在建表时,正确的选择列顺序,能够极大地提高查询效率。
因为建表时已经指定了列顺序,所以一个表只有一种前缀索引。对于使用其他列作为条件进行的查询来说,效率会低一点,这时我们可以通过创建ROLLUP来调整列顺序。
BloomFilter索引
使用场景
- BloomFilter适用于非前缀过滤
- 查询会根据该列高频过滤,而且查询条件大多是in和=过滤
- 不同于BitMap,BloomFilter适用于高基数列。比如userId这种。如果创建低基数列,则会导致BloomFilter索引失去意义,如“性别”
创建BloomFilter索引
CREATE TABLE IF NOT EXISTS sale_detail_bloom (
sale_date date NOT NULL COMMENT "销售时间",
customer_id int NOT NULL COMMENT "客户编号",
saler_id int NOT NULL COMMENT "销售员",
sku_id int NOT NULL COMMENT "商品编号",
category_id int NOT NULL COMMENT "商品分类",
sale_count int NOT NULL COMMENT "销售数量",
sale_price DECIMAL(12,2) NOT NULL COMMENT "单价",
sale_amt DECIMAL(20,2) COMMENT "销售总金额"
)
Duplicate KEY(sale_date, customer_id,saler_id,sku_id,category_id)
PARTITION BY RANGE(sale_date)
(
PARTITION P_202111 VALUES [('2021-11-01'), ('2021-12-01'))
)
DISTRIBUTED BY HASH(saler_id) BUCKETS 10
PROPERTIES (
"replication_num" = "3",
"bloom_filter_columns"="saler_id,category_id",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "MONTH",
"dynamic_partition.time_zone" = "Asia/Shanghai",
"dynamic_partition.start" = "-2147483648",
"dynamic_partition.end" = "2",
"dynamic_partition.prefix" = "P_",
"dynamic_partition.replication_num" = "3",
"dynamic_partition.buckets" = "3"
);
Bloom Filter索引的创建是通过PROPERTIES里面的bloom_filter_columns来指定。
查看BlommFilter索引
SHOW CREATE TABLE <table_name>;
修改、删除索引
删除索引即为将索引列从bloom_filter_columns属性中移除
ALTER TABLE <db.table_name> SET ("bloom_filter_columns" = "");
注意事项:
- 不支持Tinyint、Float、Double类型的列建立Bloom Filter索引
- Bloom Filter索引只对in和=过滤有加速效果
- 如果想看某个查询是否命中了Bloom Filter,可以通过查询的Profile信息查看
Bitmap索引
创建索引
CREATE INDEX [IF NOT EXISTS] index_name ON table1 (siteid) USING BITMAP COMMENT 'balabala';
查看索引
SHOW INDEX FROM example_db.table_name;
删除索引
DROP INDEX [IF EXISTS] index_name ON [db_name.]table_name;
注意事项
- bitmap索引仅在单列上创建
- bitmap索引能够应用在Duplicate、Uniq模型的所有列和Aggregate模型的key列上
- bitmap索引仅在 Segment V2 下生效。当创建 index 时,表的存储格式将默认转换为 V2 格式。
- bitmap索引支持的数据类型如下:
- TINYINT
- SMALLINT
- INT
- UNSIGNEDINT
- BIGINT
- CHAR
- VARCHAR
- DATE
- DATETIME
- LARGEINT
- DECIMAL
- BOOL