1 概念
索引用于帮助快速过滤或查找数据。
目前 Doris 主要支持两类索引:
- 内建的智能索引,包括前缀索引和ZoneMap索引
- 用户创建的二级索引,包括Bloom Filter索引和Bitmap倒排索引。
前缀索引:即在排序的基础上,实现的一种根据给定前缀列,快速查询数据的索引方式。
我们将一行数据的前 36 个字节 作为这行数据的前缀索引。当遇到 VARCHAR 类型时,前缀索引会直接截断。
2 前缀索引应用
当我们的查询条件,是前缀索引的前缀时,可以极大的加快查询速度。比如在第一个例子中,我们执行如下查询:
SELECT * FROM table WHERE user_id=1829239 and age=20;
该查询的效率会远高于如下查询:
SELECT * FROM table WHERE age=20;
所以在建表时,正确的选择列顺序,能够极大地提高查询效率。
3 匹配规则
Apache Doris的前缀索引应用于on和where,且条件表达式需要是=、<、>、<=、>=、in、between,逻辑表达式需要是and这里我们只以where进行讲解,on同理:对where中的第一个条件字段和前缀索引的第一个字段进行比较,如果相同,则匹配上,继续往下比较,如果不相同,则未匹配上,停止比较,后面的字段匹配原理和第一个字段一样。
假如对于一张表tb1,我们有如下前缀索引
Base(k1 ,k2, k3, k4, k5, k6, k7)
rollup_index(k1 ,k2, k3)
select * from tb1 where k2 = xxx #未匹配上
select * from tb1 where k1 = xxx and k2 < xxx and k4 = xxx, #匹配Base的k1、k2
select * from tb1 where k1 = xxx and k2 > xxx and k3 in(xxx) #匹配Base的k1、k2、k3 完全匹配
select * from tb1 where k1 = xxx and k2 <= xxx and k5 between xxx and k6 = xxx #匹配rollup_index的k1、k2
select * from tb1 where k1 = xxx and k2 >= xxx and k5 = xxx #rollup_index
select * from tb1 where k1 = xxx and k2 = xxx #匹配Base的k1、k2
select * from tb1 where k1 = xxx and k2 = xxx and k3 = xxx and k4 not in xxx,#匹配Base的k1、k2、k3
select * from tb1 where (k1 = xxx and k2 = xxx) or k3 = xxx #未匹配上
4 ROLLUP 调整前缀索引
因为建表时已经指定了列顺序,所以一个表只有一种前缀索引。这对于使用其他不能命中前缀索引的列作为条件进行的查询来说,效率上可能无法满足需求。因此,我们可以通过创建 ROLLUP 来人为的调整列顺序。
可以看到,ROLLUP 和 Base 表的列完全一样,只是将 user_id 和 age 的顺序调换了。那么当我们进行如下查询时:
SELECT * FROM table where age=20 and message LIKE "%error%";
会优先选择 ROLLUP 表,因为 ROLLUP 的前缀索引匹配度更高。
ROLLUP 调整前缀索引
CREATE TABLE IF NOT EXISTS test_db.example_rollup_index
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`age` SMALLINT COMMENT "用户年龄",
`message` varchar(100) COMMENT "信息",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时间"
)
AGGREGATE KEY(`user_id`, `age`, `message`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10;
创建Rollup
ALTER TABLE test_db.example_rollup_index ADD ROLLUP rollup_city(age,user_id,message,max_dwell_time,min_dwell_time);
通过命令查看完成状态
SHOW ALTER TABLE ROLLUP;
查看是否命中ROLLUP
explain SELECT * FROM test_db.example_rollup_index where age=20 and message LIKE "%error%";