跳到主要内容
版本: 最新版本-3.5

Schema 调优方法

本文档提供了通过有效的 schema 设计和基础表选择来优化 StarRocks 查询性能的实用技巧和最佳实践。 通过了解不同的表类型、键和分布策略如何影响查询执行,您可以显著提高速度和资源效率。 使用这些指南在设计 schema、选择表类型以及调整 StarRocks 环境以实现高性能分析时做出明智的决策。

表类型选择

StarRocks 支持四种表类型:Duplicate Key 表、Aggregate 表、Unique Key 表和 Primary Key 表。 所有这些都按 KEY 排序。

  • AGGREGATE KEY:当具有相同 AGGREGATE KEY 的记录加载到 StarRocks 中时,旧记录和新记录会聚合。 目前,Aggregate 表支持以下聚合函数:SUM、MIN、MAX 和 REPLACE。 Aggregate 表支持提前聚合数据,方便业务报表和多维分析。
  • DUPLICATE KEY:您只需要为 DUPLICATE KEY 表指定排序键。 具有相同 DUPLICATE KEY 的记录同时存在。 它适用于不涉及提前聚合数据的分析。
  • UNIQUE KEY:当具有相同 UNIQUE KEY 的记录加载到 StarRocks 中时,新记录会覆盖旧记录。 UNIQUE KEY 表类似于带有 REPLACE 函数的 Aggregate 表。 两者都适用于涉及常量更新的分析。
  • PRIMARY KEY:Primary Key 表保证记录的唯一性,并允许您执行实时更新。
CREATE TABLE site_visit
(
siteid INT,
city SMALLINT,
username VARCHAR(32),
pv BIGINT SUM DEFAULT '0'
)
AGGREGATE KEY(siteid, city, username)
DISTRIBUTED BY HASH(siteid);


CREATE TABLE session_data
(
visitorid SMALLINT,
sessionid BIGINT,
visittime DATETIME,
city CHAR(20),
province CHAR(20),
ip varchar(32),
browser CHAR(20),
url VARCHAR(1024)
)
DUPLICATE KEY(visitorid, sessionid)
DISTRIBUTED BY HASH(sessionid, visitorid);

CREATE TABLE sales_order
(
orderid BIGINT,
status TINYINT,
username VARCHAR(32),
amount BIGINT DEFAULT '0'
)
UNIQUE KEY(orderid)
DISTRIBUTED BY HASH(orderid);

CREATE TABLE sales_order
(
orderid BIGINT,
status TINYINT,
username VARCHAR(32),
amount BIGINT DEFAULT '0'
)
PRIMARY KEY(orderid)
DISTRIBUTED BY HASH(orderid);

Colocate 表

为了加速查询,具有相同分布的表可以使用公共 bucketing 列。 在这种情况下,数据可以在本地连接,而无需在 join 操作期间跨集群传输。

CREATE TABLE colocate_table
(
visitorid SMALLINT,
sessionid BIGINT,
visittime DATETIME,
city CHAR(20),
province CHAR(20),
ip varchar(32),
browser CHAR(20),
url VARCHAR(1024)
)
DUPLICATE KEY(visitorid, sessionid)
DISTRIBUTED BY HASH(sessionid, visitorid)
PROPERTIES(
"colocate_with" = "group1"
);

有关 colocate join 和副本管理的更多信息,请参见Colocate join

扁平表和星型 schema

StarRocks 支持星型 schema,它在建模方面比扁平表更灵活。 您可以创建一个视图来替换建模期间的扁平表,然后从多个表查询数据以加速查询。

扁平表有以下缺点

  • 维度更新成本高昂,因为扁平表通常包含大量的维度。 每次更新维度时,都必须更新整个表。 随着更新频率的增加,情况会恶化。
  • 维护成本高昂,因为扁平表需要额外的开发工作量、存储空间和数据回填操作。
  • 数据摄取成本高昂,因为扁平表有很多字段,而 Aggregate 表可能包含更多的键字段。 在数据加载期间,需要对更多字段进行排序,这会延长数据加载时间。

如果您对查询并发性或低延迟有很高的要求,您仍然可以使用扁平表。

分区和分桶

StarRocks 支持两个级别的分区:第一级是 RANGE 分区,第二级是 HASH 分桶。

  • RANGE 分区:RANGE 分区用于将数据划分为不同的间隔(可以理解为将原始表划分为多个子表)。 大多数用户选择按时间设置分区,这有以下优点

    • 更容易区分冷热数据
    • 能够利用 StarRocks 分层存储(SSD + SATA)
    • 按分区删除数据更快
  • HASH 分桶:根据哈希值将数据划分为不同的桶。

    • 建议使用区分度高的列进行分桶,以避免数据倾斜。
    • 为了方便数据恢复,建议将每个桶中压缩数据的大小保持在 100 MB 到 1 GB 之间。 我们建议您在创建表或添加分区时配置适当数量的桶。
    • 不建议使用随机分桶。 创建表时,必须显式指定 HASH 分桶列。

稀疏索引和 bloomfilter 索引

StarRocks 以有序方式存储数据,并以 1024 行为粒度构建稀疏索引。

StarRocks 在 schema 中选择一个固定长度的前缀(当前为 36 个字节)作为稀疏索引。

创建表时,建议将常用过滤字段放在 schema 声明的开头。 必须首先放置具有最高区分度和查询频率的字段。

VARCHAR 字段必须放在稀疏索引的末尾,因为索引从 VARCHAR 字段截断。 如果 VARCHAR 字段首先出现,则索引可能小于 36 个字节。

以上面的 site_visit 表为例。 该表有四列:siteid, city, username, pv。 排序键包含三列 siteid, city, username,分别占用 4、2 和 32 个字节。 因此,前缀索引(稀疏索引)可以是 siteid + city + username 的前 30 个字节。

除了稀疏索引之外,StarRocks 还提供 bloomfilter 索引,它对于过滤具有高区分度的列非常有效。 如果要将 VARCHAR 字段放在其他字段之前,可以创建 bloomfilter 索引。

倒排索引

StarRocks 采用 Bitmap 索引技术来支持倒排索引,倒排索引可以应用于 Duplicate Key 表的所有列以及 Aggregate 表和 Unique Key 表的键列。 Bitmap 索引适用于值范围较小的列,例如性别、城市和省份。 随着范围的扩大,bitmap 索引也会并行扩展。

物化视图 (rollup)

rollup 本质上是原始表(基表)的物化索引。 创建 rollup 时,只能选择基表的一些列作为 schema,并且 schema 中字段的顺序可以与基表的字段顺序不同。 以下是使用 rollup 的一些用例

  • 基表中的数据聚合不高,因为基表具有区分度高的字段。 在这种情况下,您可以考虑选择一些列来创建 rollup。 以上面的 site_visit 表为例

    site_visit(siteid, city, username, pv)

    siteid 可能会导致数据聚合不良。 如果您需要经常按城市计算 PV,则可以创建一个仅包含 citypv 的 rollup。

    ALTER TABLE site_visit ADD ROLLUP rollup_city(city, pv);
  • 无法命中基表中的前缀索引,因为构建基表的方式无法覆盖所有查询模式。 在这种情况下,您可以考虑创建 rollup 来调整列的顺序。 以上面的 session_data 表为例

    session_data(visitorid, sessionid, visittime, city, province, ip, browser, url)

    如果除了 visitorid 之外,还需要分析 browserprovince 的访问量,则可以创建一个单独的 rollup

    ALTER TABLE session_data
    ADD ROLLUP rollup_browser(browser,province,ip,url)
    DUPLICATE KEY(browser,province);

Schema 更改

StarRocks 中有三种更改 schema 的方法:排序 schema 更改、直接 schema 更改和链接 schema 更改。

  • 排序 schema 更改:更改列的排序并重新排序数据。 例如,删除排序 schema 中的列会导致数据重新排序。

    ALTER TABLE site_visit DROP COLUMN city;

  • 直接 schema 更改:转换数据而不是重新排序数据,例如,更改列类型或向稀疏索引添加列。

    ALTER TABLE site_visit MODIFY COLUMN username varchar(64);

  • 链接 schema 更改:完成更改而无需转换数据,例如,添加列。

    ALTER TABLE site_visit ADD COLUMN click bigint SUM default '0';

    建议您在创建表时选择合适的 schema 以加速 schema 更改。