Doris–基础–5.2–索引
1、介绍
- 索引用于帮助快速过滤或查找数据。
1.1、Doris 主要支持两类索引
- 内建的智能索引,包括
- 前缀索引
- ZoneMap索引
- 用户创建的二级索引
- Bloom Filter索引
- Bitmap倒排索引。
2、前缀索引
- 在排序的基础上,实现的一种根据给定前缀列,快速查询数据的索引方式。
- 我们将一行数据的前 36 个字节 作为这行数据的前缀索引。当遇到 VARCHAR 类型时,前缀索引会直接截断。
2.1、匹配规则
- Doris的前缀索引 应用于 on和where
- Doris的前缀索引 条件表达式 需要是=、<、>、<=、>=、in、between
- Doris的前缀索引 逻辑表达式 需要是and
- 匹配规则:
- 这里我们只以where进行讲解,on同理
- 对where中的第一个条件字段和前缀索引的第一个字段进行比较,如果相同,则匹配上,继续往下比较,如果不相同,则未匹配上,停止比较,后面的字段匹配原理和第一个字段一样。
2.2、举例
2.2.1、举例1
当我们的查询条件,是前缀索引的前缀时,可以极大的加快查询速度。比如在第一个例子中,我们执行如下查询:
SELECT * FROM table WHERE user_id=1829239 and age=20; -- 高效率查询
SELECT * FROM table WHERE age=20; -- 低效率查询
2.2.2、举例2
假如对于一张表tb1,我们有如下前缀索引
Base(k1 ,k2, k3, k4, k5, k6, k7)
rollup_index(k1 ,k2, k3)
结论
# 未匹配上
select * from tb1 where k2 = xxx
#匹配Base的k1、k2
select * from tb1 where k1 = xxx and k2 < xxx and k4 = xxx
#匹配Base的k1、k2、k3 完全匹配
select * from tb1 where k1 = xxx and k2 > xxx and k3 in(xxx)
# 匹配rollup_index的k1、k2
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
# 匹配Base的k1、k2
select * from tb1 where k1 = xxx and k2 = xxx
# 匹配Base的k1、k2、k3
select * from tb1 where k1 = xxx and k2 = xxx and k3 = xxx and k4 not in xxx
# 未匹配上
select * from tb1 where (k1 = xxx and k2 = xxx) or k3 = xxx
2.3、ROLLUP 调整前缀索引
2.3.1、介绍
因为建表时已经指定了列顺序,所以一个表只有一种前缀索引。这对于使用其他不能命中前缀索引的列作为条件进行的查询来说,效率上可能无法满足需求。因此,我们可以通过创建 ROLLUP 来人为的调整列顺序。
2.3.2、举例1
可以看到,ROLLUP 和 Base 表的列完全一样,只是将 user_id 和 age 的顺序调换了。那么当我们进行如下查询时
SELECT * FROM table where age=20 and message LIKE "%error%";
会优先选择 ROLLUP 表,因为 ROLLUP 的前缀索引匹配度更高。
2.3.2、举例2(执行的时候,BE就挂了)
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;
insert into test_db.example_rollup_index values(1,10,"error1",20,10);
insert into test_db.example_rollup_index values(2,10,"error2",50,10);
insert into test_db.example_rollup_index values(2,10,"error2",20,1);
insert into test_db.example_rollup_index values(4,10,"error4",20,10);
insert into test_db.example_rollup_index values(5,10,"error5",20,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=10 and message LIKE "%error%";