Doris索引

429 阅读3分钟

索引

索引用于帮助快速过滤或查找数据。

目前Doris支持两类索引:内建的智能索引,包括前缀索引和ZoneMap索引;用户创建的二级索引,包括Bloom Filter索引和Bitmap索引。

前缀索引

本质上,Doris的数据存储在类似SSTable(Sorted String Table)的数据结构中。该结构是一种有序的数据结构,可以按照指定的列进行排序存储。在这种数据结构上,以排序列作为条件查找,会非常高效。

而前缀索引,是在排序的基础上实现的一种根据给定前缀列,快速查询数据的索引方式。

前缀索引是将一行数据的前36个自己作为这行数据的前缀索引,并且当遇到VARCHAR类型时,前缀索引直接截断。

举例说明:

  1. 下表的前缀索引为user_id(8 Bytes) + age(4 Bytes) + message(prefix 20 Bytes)
ColumnNameType
user_idBIGINT
ageINT
messageVARCHAR(100)
max_dwell_timeDATETIME
  1. 下表的前缀索引为user_name(20 Bytes),即使没有达到 36 个字节,因为遇到 VARCHAR,所以直接截断,不再往后继续
ColumnNameType
user_nameVARCHAR(20)
ageINT
messageVARCHAR(100)

当我们的查询条件,是前缀索引的前缀时,可以极大的加快查询速度。比如在第一个例子中,我们执行如下查询:

SELECT * FROM table WHERE user_id=1829239 and age=20

该查询的效率会远高于如下查询:

SELECT * FROM table WHERE age=20

所以在建表时,正确的选择列顺序,能够极大地提高查询效率。

因为建表时已经指定了列顺序,所以一个表只有一种前缀索引。对于使用其他列作为条件进行的查询来说,效率会低一点,这时我们可以通过创建ROLLUP来调整列顺序。

BloomFilter索引

使用场景

  1. BloomFilter适用于非前缀过滤
  2. 查询会根据该列高频过滤,而且查询条件大多是in和=过滤
  3. 不同于BitMap,BloomFilter适用于高基数列。比如userId这种。如果创建低基数列,则会导致BloomFilter索引失去意义,如“性别”

创建BloomFilter索引

CREATE TABLE IF NOT EXISTS sale_detail_bloom  (
    sale_date date NOT NULL COMMENT "销售时间",
    customer_id int NOT NULL COMMENT "客户编号",
    saler_id int NOT NULL COMMENT "销售员",
    sku_id int NOT NULL COMMENT "商品编号",
    category_id int NOT NULL COMMENT "商品分类",
    sale_count int NOT NULL COMMENT "销售数量",
    sale_price DECIMAL(12,2) NOT NULL COMMENT "单价",
    sale_amt DECIMAL(20,2)  COMMENT "销售总金额"
)
Duplicate  KEY(sale_date, customer_id,saler_id,sku_id,category_id)
PARTITION BY RANGE(sale_date)
(
PARTITION P_202111 VALUES [('2021-11-01'), ('2021-12-01'))
)
DISTRIBUTED BY HASH(saler_id) BUCKETS 10
PROPERTIES (
"replication_num" = "3",
"bloom_filter_columns"="saler_id,category_id",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "MONTH",
"dynamic_partition.time_zone" = "Asia/Shanghai",
"dynamic_partition.start" = "-2147483648",
"dynamic_partition.end" = "2",
"dynamic_partition.prefix" = "P_",
"dynamic_partition.replication_num" = "3",
"dynamic_partition.buckets" = "3"
);

Bloom Filter索引的创建是通过PROPERTIES里面的bloom_filter_columns来指定。

查看BlommFilter索引

SHOW CREATE TABLE <table_name>;

修改、删除索引

删除索引即为将索引列从bloom_filter_columns属性中移除

ALTER TABLE <db.table_name> SET ("bloom_filter_columns" = "");

注意事项:

  1. 不支持Tinyint、Float、Double类型的列建立Bloom Filter索引
  2. Bloom Filter索引只对in和=过滤有加速效果
  3. 如果想看某个查询是否命中了Bloom Filter,可以通过查询的Profile信息查看

Bitmap索引

创建索引

CREATE INDEX [IF NOT EXISTS] index_name ON table1 (siteid) USING BITMAP COMMENT 'balabala';

查看索引

SHOW INDEX FROM example_db.table_name;

删除索引

DROP INDEX [IF EXISTS] index_name ON [db_name.]table_name;

注意事项

  • bitmap索引仅在单列上创建
  • bitmap索引能够应用在Duplicate、Uniq模型的所有列和Aggregate模型的key列上
  • bitmap索引仅在 Segment V2 下生效。当创建 index 时,表的存储格式将默认转换为 V2 格式。
  • bitmap索引支持的数据类型如下:
    • TINYINT
    • SMALLINT
    • INT
    • UNSIGNEDINT
    • BIGINT
    • CHAR
    • VARCHAR
    • DATE
    • DATETIME
    • LARGEINT
    • DECIMAL
    • BOOL
    开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情