tencent cloud

文档反馈

索引、排序列和前缀索引

最后更新时间:2024-06-27 10:55:17

    索引

    Doris 支持比较丰富的索引结构来减少数据的扫描和提高查询效率,目前支持的索引类型有:
    Sorted Compound Key Index,可以最多指定三个列组成复合排序键,通过该索引,能够有效进行数据裁剪,从而能够更好支持高并发的报表场景 。
    Z-order Index :可以高效对数据模型中的任意字段组合进行范围查询。
    Min/Max :有效过滤数值类型的等值和范围查询。
    Bloom Filter :对高基数列的等值过滤裁剪非常有效。
    Invert Index :能够对任意字段实现快速检索。
    不同于传统的数据库设计,Doris 不支持在任意列上创建索引。Doris 这类 MPP 架构的 OLAP 数据库,通常都是通过提高并发来处理大量数据的。

    排序列(Sort Key)

    为了提高查询性能,Doris 优化了数据存储的组织结构。本质上,Doris 的数据存储在类似 SSTable(Sorted String Table)的数据结构中。该结构是一种有序的数据结构,可以按照指定的列进行排序存储(可以是一列或者多列),这些列即称为排序列。在这种数据结构上,以排序列作为条件进行查找,会非常的高效。
    在 Aggregate、Unique 和 Duplicate 三种数据模型中。底层的数据存储,是按照各自建表语句中,AGGREGATE KEY、UNIQUE KEY 和 DUPLICATE KEY 中指定的列进行排序存储的。Rollup 可以指定自己的排序列,但排序列必须是 Rollup 列顺序的前缀。
    注意
    在建表语句中的列定义中,排序列的定义必须出现在其他列的定义之前。
    排序列的顺序是由 create table 语句中的列顺序决定的。

    前缀索引

    即在排序的数据结构(SSTable)基础上,实现的一种根据给定前缀列,快速查询数据的索引方式。对于能使用上排序结构的查询,Doris 采用二分查找算法定位到目标数据的区间。但如果表中数据行数很多,直接对排序列进行二分查找需要把所有 filter 列的数据都加载到内存中,这会消耗大量内存空间。为优化这个细节,Doris 在 Sort Key 的基础上引入稀疏的 Shortkey Index(前缀索引),Sortkey Index 的内容会比数据量少1024倍(Doris 把每1024行数据组成一个逻辑数据块 (称作 Data Block),每个 Data Block 在前缀索引中存储一行索引),因此会全量缓存在内存中,实际查找的过程中可以有效加速查询。
    当 Sort Key 列数非常多时,会占用大量内存,为了性能考虑,对前缀索引项做了限制:
    最多可选取 3 列作为 Shortkey 列。
    不能使用 FLOAT / DOUBLE 类型的列。
    只能按排序键的顺序来构造前缀索引。
    VARCHAR / CHAR 类型列只能出现一次,并且只能是最后位置。
    所有列字节数不超过36字节,VARCHAR / CHAR 列按剩余字节数折断。
    当用户在建表语句中指定 short_key 属性时,例如"short_key" = "4"指定4个列作为 short_key, 可突破上述限制。

    示例

    1. 以下表结构的前缀索引为 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
    min_dwell_time
    DATETIME
    2. 以下表结构的前缀索引为 user_name(20 Bytes)。即使没有达到 36 个字节,因为遇到 VARCHAR,所以直接截断,不再往后继续。
    ColumnName
    Type
    user_name
    VARCHAR(20)
    age
    INT
    message
    VARCHAR(100)
    max_dwell_time
    DATETIME
    min_dwell_time
    DATETIME
    当我们的查询条件是前缀索引的前缀时,可以极大的加快查询速度。例如在第一个例子中,我们执行如下查询:
    SELECT * FROM table WHERE user_id=1829239 and age=20
    该查询的效率会远高于如下查询:
    SELECT * FROM table WHERE age=20
    所以在建表时,正确的选择列顺序,能够极大地提高查询效率

    最佳实践

    通过 ROLLUP 来调整前缀索引

    因为建表时已经指定了列顺序,所以一个表只有一种前缀索引。这对于使用其他不能命中前缀索引的列作为条件进行的查询来说,效率上可能无法满足需求。因此,我们可以通过创建 ROLLUP 来人为的调整列顺序。

    优化排序列的先后顺序来提高查询性能

    当 Sort Key 涉及多个列的时候,需要注意先后顺序,区分度高、经常查询的列建议放在前面。
    注意排序列的数量:
    1. 如果选择了大量的列用于排序列,那么数据导入时排序的开销会增大整个导入过程的耗时。
    2. 设计良好的少量排序列也能快速定位到数据行所在的位置,增加更多列进行排序也不会带来查询的提升。
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持