索引
建立索引的方法
在 Doris 中,建立索引通常是在创建表或修改表时进行的。以下是如何在创建表时添加索引的基本语法:
CREATE TABLE example_db.table_name (
`column1` DataType1,
`column2` DataType2,
...
INDEX index_name (column_list)
) ENGINE=OLAP
DUPLICATE KEY(`column1`, `column2`)
...
或者,如果表已经存在,可以使用 ALTER TABLE
语句添加索引:
ALTER TABLE example_db.table_name ADD INDEX index_name (column_list);
索引的种类
前缀索引(Prefix Index):
前缀索引是对字符串列的前几个字符建立的索引。这种索引适用于列值是长字符串,但查询时通常只需要匹配前几个字符的场景。
在创建表时指定前缀索引的长度:
CREATE TABLE example_db.table_name ( `column1` VARCHAR(50) WITH PRECISION 10, ... ) ENGINE=OLAP ...
这里的
WITH PRECISION 10
表示对column1
的前10个字符建立索引。
Bitmap 索引:
Bitmap 索引适用于那些具有离散值的列,特别是那些取值有限的列,如性别、国家代码等。
Bitmap 索引可以显著减少数据存储空间,并提高查询效率,特别是在进行等值查询和范围查询时。
创建 Bitmap 索引:
CREATE TABLE example_db.table_name ( `column1` INT, ... ) ENGINE=OLAP UNIQUE KEY(`column1`) PROPERTIES ( "index_type" = "BITMAP" );
BloomFilter 索引:
BloomFilter 索引是一种概率型数据结构,用于判断一个元素是否在一个集合中。
它可以用来加速“不等于”查询,减少回表操作,提高查询性能。
创建 BloomFilter 索引:
CREATE TABLE example_db.table_name ( `column1` INT, ... ) ENGINE=OLAP UNIQUE KEY(`column1`) PROPERTIES ( "bloom_filter_columns" = "column1" );
ZORDER 索引:
ZORDER 索引是一种多列联合索引,它将多列的值编码为一个单一的数值,用于多维数据的排序和查询。
这种索引适合于需要对多个维度进行排序的场景,如地理空间数据。
创建 ZORDER 索引:
CREATE TABLE example_db.table_name ( `column1` INT, `column2` INT, ... ) ENGINE=OLAP UNIQUE KEY(`column1`, `column2`) PROPERTIES ( "index_type" = "ZORDER" );
分区分桶
参考链接:基本概念 - Apache Doris
分区(Partition)
分区是将表中的数据分割成多个部分,每个部分包含原始表的一个子集。在 Doris 中,分区可以基于不同策略,如范围(Range)或列表(List)。分区的主要目的是:
数据隔离:将数据逻辑上隔离,便于管理。
优化查询:查询时可以只扫描相关分区,减少数据扫描范围。
数据维护:方便对特定分区进行维护操作,如删除旧数据。
在 Doris 中创建分区表的示例:
CREATE TABLE example_db.table_name (
`column1` DataType1,
`column2` DataType2,
...
) ENGINE=OLAP
PARTITION BY RANGE(`column1`) (
PARTITION p1 VALUES LESS THAN ('value1'),
PARTITION p2 VALUES LESS THAN ('value2'),
...
);
分桶(Bucket)
分桶是将数据在物理上进一步细分为多个桶(Bucket),每个桶包含多行数据。Doris 使用哈希分桶来分布数据,以确保数据均匀分布在不同的桶中。分桶的主要目的是:
数据均匀分布:通过哈希分桶保证数据均匀分布,避免数据倾斜。
并行处理:查询时可以并行处理不同桶中的数据,提高查询效率。
数据局部性:相关数据更有可能被存储在同一个桶中,提高缓存命中率。
在 Doris 中创建分桶表的示例:
CREATE TABLE example_db.table_name (
`column1` DataType1,
`column2` DataType2,
...
) ENGINE=OLAP
DUPLICATE KEY(`column1`)
DISTRIBUTED BY HASH(`column1`) BUCKETS 16;
在这个例子中,column1
是分桶的依据,表被分为 16 个桶。
分区和分桶的结合使用
在 Doris 中,分区和分桶可以结合使用,以实现更细粒度的数据管理和优化。数据首先根据分区条件被分配到不同的分区,然后在每个分区内进一步被分桶。
CREATE TABLE example_db.table_name (
`column1` DataType1,
`column2` DataType2,
...
) ENGINE=OLAP
PARTITION BY RANGE(`column1`) (
PARTITION p1 VALUES LESS THAN ('value1'),
PARTITION p2 VALUES LESS THAN ('value2'),
...
)
DISTRIBUTED BY HASH(`column2`) BUCKETS 16;
在这个例子中,数据首先根据 column1
的值被分配到不同的分区,然后在每个分区内根据 column2
的值被进一步分桶。
与 MySQL 相比
Apache Doris 和 MySQL 在分区分桶方面有一些相似的概念,但在实现和使用上有所不同。以下是两者在分区分桶方面的对比:
分区(Partition)
MySQL:
MySQL 支持范围分区(RANGE)和列表分区(LIST),允许用户根据某个列的值将数据划分到不同的分区。
分区可以在创建表时定义,也可以后续通过
ALTER TABLE
语句添加。MySQL 的分区表在逻辑上仍然是一个单一的表,但物理上数据被存储在不同的分区中。
Doris:
Doris 同样支持范围分区(RANGE)和列表分区(LIST),但实现方式和使用场景更倾向于大规模数据集的OLAP查询。
分区在Doris中是数据分布和存储的重要组成部分,它允许Doris在查询时只扫描相关的分区,提高查询效率。
分桶(Bucket)
MySQL:
MySQL 8.0 引入了虚拟列的概念,允许用户基于虚拟列的值进行分桶,这类似于Doris的分桶概念。
MySQL的分桶不是基于物理分布,而是逻辑上的分组,它不直接影响数据的物理存储。
Doris:
Doris 的分桶是基于物理分布的,它使用哈希分桶来确保数据均匀分布在不同的桶(Bucket)中。
分桶是Doris数据模型的一部分,可以在创建表时定义,并且直接影响数据的物理存储和查询性能。
相似之处:
两者都允许用户通过分区来优化查询性能,减少数据扫描的范围。
两者都支持基于列值的逻辑分区。
不同之处:
MySQL 的分区更多地用于简化数据管理,如归档旧数据,而Doris的分区更侧重于提高查询性能。
Doris 的分桶是物理分布的,直接影响数据的存储和查询,而MySQL的分桶(虚拟列)更多是逻辑上的分组。
Doris 的分桶数量和策略在创建表时定义,并且与数据模型(如 Aggregate、Unique、Duplicate)紧密相关,而MySQL的分桶策略更灵活,可以在查询时动态指定。