> 文章列表 > Doris(14):索引

Doris(14):索引

Doris(14):索引

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%";