- Doris 前缀索引
doris不支持在任意列上创建索引,而是按照指定的列对数据进行排序存储,在这种数据结构上,以排序列作为条件查询会非常的高效。
在Aggregate,Uniq,Duplicate三种数据模型中,底层的数据存储,是按照各自建表语句中,AGGREGATE KEY,UNIQ KEY,DUPLICATE KEY中指定的列进行排序存储。
doris创建的索引是稀疏索引,将一行数据按照排序列的顺序进行存储,然后取一行数据中前面不多于36个字节的数据作为索引。因此在查询时。将查询条件按照排序列进行排序,会提高查询效率。 因此,排序列在建表语句中必须放在其他列的定义前面,并且顺序与建表语句保持一致。
-- AGGREGATE KEY(siteid, city, username) 排序列的顺序与创建表的字段顺序一致
CREATE TABLE visit
(
siteid INT,
city SMALLINT,
username VARCHAR(32),
pv BIGINT SUM DEFAULT '0'
)
AGGREGATE KEY(siteid, city, username)
DISTRIBUTED BY HASH(siteid) BUCKETS 10
PROPERTIES("replication_num" = "1");
-- 查询条件和排序列的顺序一致
select * from visit where siteid = and city = and username =
2. ROLLUP
在 Doris 中,我们将用户通过建表语句创建出来的表成为 Base 表(Base Table)。Base 表中保存着按用户建表语句指定的方式存储的基础数据。
在 Base 表之上,我们可以创建任意多个 ROLLUP 表。这些 ROLLUP 的数据是基于 Base 表产生的,并且在物理上是独立存储的。Rollup 本质上可以理解为原始表(Base Table)的一个物化索引。建立 Rollup 时可只选取 Base Table 中的部分列作为 Schema。Schema 中的字段顺序也可与 Base Table 不同。
也就是说,rollup表其实是保存了base表中的一部分字段的数据。例如
-- rollup_visit中只保存了siteid这一个维度列以及pv这个value列
alter table visit add rollup rollup_visit(siteid,pv);
这样当我们按照siteid去统计pv的聚合值的时候,可以通过查询
-- 查询的依旧是原始表
select siteid,sum(pv) from visit group by siteid;
-- 查询计划
select siteid,sum(pv) from visit group by siteid;
rollup也是有前缀索引的,sql语句按照前缀匹配对应的rollup,自动去对应的rollup中查询对应的数据。
因此,我们可以通过创建不同的rollup,来指定不同的排序列的顺序,以适应不同的查询方式。
ROLLUP 是附属于 Base 表的,可以看做是 Base 表的一种辅助数据结构。用户可以在 Base 表的基础上,创建或删除 ROLLUP,但是不能在查询中显式的指定查询某 ROLLUP。是否命中 ROLLUP 完全由 Doris 系统自动决定。
ROLLUP 的数据是独立物理存储的。因此,创建的 ROLLUP 越多,占用的磁盘空间也就越大。同时对导入速度也会有影响,但是不会降低查询效率;
ROLLUP 的数据更新与 Base 表示完全同步的;
查询能否命中 ROLLUP 的一个必要条件(非充分条件)是,查询所涉及的所有列(包括 select list 和 where 中的查询条件列等)都存在于该 ROLLUP 的列中。否则,查询只能命中 Base 表。