velodb-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVeloDB Best Practices
VeloDB 最佳实践
Problem-first table design intelligence for Apache Doris. 37 rules, 7 use case templates, 4 sizing guides. All details indirectory and compiledreferences/.AGENTS.md
面向 Apache Doris 的问题导向型表设计指南。 包含37条规则、7个用例模板、4份容量规划指南。 所有详情请查看目录及编译后的references/文件。AGENTS.md
1 ▸ Problem-First Routing
1 ▸ 问题导向型路由
I need to build…
我需要构建…
| Problem | Template(s) | Key Rules |
|---|---|---|
| Real-time log/event analytics | | DUPLICATE, RANGE partition, dynamic TTL, ZSTD |
| CDC / MySQL sync to Doris | | UNIQUE MoW, sequence_col, HASH bucket |
| Dashboard with pre-aggregated metrics | | AGGREGATE, BITMAP_UNION, sync MV |
| User-facing API with low-latency point queries | | UNIQUE MoW, store_row_column, BloomFilter |
| Star schema with JOIN-heavy analytics | | Colocation, same bucket key/count |
| Small dimension / lookup table | | DUPLICATE, RANDOM bucket, 3 buckets |
| Observability (logs + traces + metrics) | | 3 tables: DUP logs, DUP traces, AGG metrics |
| Vehicle/fleet tracking | | Time-series + point-query hybrid |
| E-commerce order analytics | | Star schema + AGG rollups |
| Full-text search / content search | | Inverted index, MATCH, BM25 |
| User behavior / funnel analysis | | BITMAP_UNION, bitmap_intersect |
| Semi-structured JSON data | | VARIANT type, schema_template |
| 业务场景 | 模板 | 核心规则 |
|---|---|---|
| 实时日志/事件分析 | | DUPLICATE、RANGE 分区、动态TTL、ZSTD |
| CDC / MySQL 同步至 Doris | | UNIQUE MoW、sequence_col、HASH 分桶 |
| 含预聚合指标的仪表板 | | AGGREGATE、BITMAP_UNION、同步MV |
| 低延迟点查询的用户API | | UNIQUE MoW、store_row_column、BloomFilter |
| 多JOIN分析的星型 schema | | Colocation、相同分桶键/数量 |
| 小维度/ lookup表 | | DUPLICATE、RANDOM 分桶、3个分桶 |
| 可观测性(日志+链路追踪+指标) | | 3张表:DUP日志表、DUP链路追踪表、AGG指标表 |
| 车辆/车队追踪 | | 时序数据+点查询混合模式 |
| 电商订单分析 | | 星型schema+AGG预聚合 |
| 全文检索/内容搜索 | | 倒排索引、MATCH、BM25 |
| 用户行为/漏斗分析 | | BITMAP_UNION、bitmap_intersect |
| 半结构化JSON数据 | | VARIANT类型、schema_template |
My query is slow after evidence shows…
证据显示我的查询变慢…
For live slow-query or runtime diagnosis, do not use this table as the first response. First read and collect or attempt evidence (, , , , , or ). Use this table only after evidence points to the symptom.
references/cli-investigation.mdprofile getprofile listprofile historytabletEXPLAINauth status| Symptom | Check These Rules | Quick Fix |
|---|---|---|
| Full table scan on WHERE clause | | Move filtered column to sort key position 1 |
| JOINs are slow / shuffle | | Small dims (<1GB): broadcast + runtime filter. Large: colocation |
| COUNT DISTINCT is slow | | Switch to BITMAP_UNION aggregation |
| LIKE '%keyword%' is slow | | Add NGram BloomFilter index |
| Point query latency too high | | Enable store_row_column + Prepared Statement |
| Storage growing too fast | | AUTO PARTITION + ZSTD compression + scheduled DROP PARTITION |
| Sync MV not being used | | Use raw columns (not date_trunc) in MV GROUP BY; unique aliases |
| Async MV rewrite fails | | Check State/RefreshState; query MV directly if predicate fails |
| Data skew / hot tablets | | Composite bucket key or RANDOM |
| Import fails / data version error | | Check concurrent MV refresh limit (max 3) |
| VARCHAR in key kills perf | | Move VARCHAR after fixed-length types |
| Writes slow on UNIQUE table | | Ensure MoW is enabled (not MoR) |
对于实时慢查询或运行时诊断,请勿直接使用下表作为第一响应。请先阅读 并收集或尝试获取证据(、、、、 或 )。仅当证据指向对应症状时,再使用下表。
references/cli-investigation.mdprofile getprofile listprofile historytabletEXPLAINauth status| 症状 | 检查对应规则 | 快速修复方案 |
|---|---|---|
| WHERE子句触发全表扫描 | | 将过滤列移至排序键第1位 |
| JOIN操作缓慢/数据 shuffle | | 小维度表(<1GB):广播+运行时过滤;大表:Colocation |
| COUNT DISTINCT 缓慢 | | 切换为 BITMAP_UNION 聚合 |
| LIKE '%keyword%' 缓慢 | | 添加NGram BloomFilter索引 |
| 点查询延迟过高 | | 启用 store_row_column + Prepared Statement |
| 存储增长过快 | | AUTO分区 + ZSTD压缩 + 定期删除分区 |
| 同步MV未被使用 | | MV的GROUP BY使用原始列(而非date_trunc);使用唯一别名 |
| 异步MV重写失败 | | 检查State/RefreshState;若谓词失败,直接查询MV |
| 数据倾斜/热点Tablet | | 复合分桶键或RANDOM分桶 |
| 导入失败/数据版本错误 | | 检查并发MV刷新限制(最多3个) |
| 键中包含VARCHAR导致性能下降 | | 将VARCHAR列移至定长类型之后 |
| UNIQUE表写入缓慢 | | 确保启用MoW(而非MoR) |
2 ▸ Pre-Flight Checklist (Before Any CREATE TABLE)
2 ▸ 预检查清单(创建任何表之前)
Run through this checklist in order. Each step references the relevant rule:
- Data model — UNIQUE (updates?) vs DUPLICATE (append?) vs AGGREGATE (pre-agg only?) →
schema-model-choose-for-workload - Partition strategy — Time-series? AUTO PARTITION preferred. Small table? Skip. Do NOT combine AUTO with dynamic_partition. →
schema-partition-* - Bucket key + count — HASH on JOIN key. Calculate explicit count: . Use explicit fallback counts when volume is unknown: 3 for small dimensions, 8 for medium tables, 16-32 for large daily fact tables. →
daily_GB / target_tablet_GBschema-bucket-* - Sort key order — High-selectivity first, fixed-length before VARCHAR →
schema-keys-* - Data types — Native types, not STRING. DECIMAL not FLOAT. →
schema-types-* - Indexes — BloomFilter for equality, Inverted for text, NGram for LIKE →
schema-index-* - Properties — MoW enabled? Compression? Cloud mode replication_num=1? →
schema-props-* - DDL hard constraints (VeloDB rejects DDL if any violated):
- UNIQUE KEY + PARTITION BY RANGE → partition column MUST be in the UNIQUE KEY:
UNIQUE KEY(id, dt) PARTITION BY RANGE(dt) - Key columns must be the FIRST N columns in schema, same order — put key cols first, non-key after. Example: means schema must start with
UNIQUE KEY(account_id, symbol)— never place non-key columns between key columnsaccount_id, symbol, ... - only works on UNIQUE MoW — NOT on AGGREGATE or DUPLICATE
store_row_column = "true" - AUTO PARTITION requires AND empty parens:
date_trunc()— bare column name fails, missingAUTO PARTITION BY RANGE(date_trunc(col, 'day')) ()fails() - Dynamic partition requires explicit clause in DDL — properties alone are not enough
PARTITION BY RANGE(col) () - Do not set ; put the numeric count only in
dynamic_partition.bucketsDISTRIBUTED BY HASH(col) BUCKETS N - only for DUPLICATE tables — fails on UNIQUE
compaction_policy = "time_series" - Async MV refresh: use or
REFRESH AUTO ON SCHEDULE EVERY 10 MINUTE— NOTREFRESH COMPLETE ON SCHEDULE EVERY 10 MINUTE, NOTREFRESH SCHEDULE EVERY. Minimum interval: 1 MINUTEREFRESH ASYNC EVERY(INTERVAL ...) - MV using /
NOW(): addCURDATE()PROPERTIES ("enable_nondeterministic_function" = "true") - BOOLEAN defaults must be quoted: not
DEFAULT "true"DEFAULT TRUE - BloomFilter index: use — NOT inline
PROPERTIES ("bloom_filter_columns" = "col1,col2")INDEX ... USING BLOOM FILTER - AGGREGATE column syntax: aggregation function BEFORE default: — NOT
col BIGINT SUM DEFAULT "0"col BIGINT DEFAULT "0" SUM - AGGREGATE only works for VARCHAR — fails on INT, DATE, DECIMAL, BIGINT. Omit DEFAULT entirely for REPLACE_IF_NOT_NULL on non-string types:
DEFAULT "null"(notvip_level INT REPLACE_IF_NOT_NULL)DEFAULT "null" - is a session variable, NOT a table property
enable_unique_key_partial_update - Full details:
schema-ddl-gotchas
- UNIQUE KEY + PARTITION BY RANGE → partition column MUST be in the UNIQUE KEY:
按顺序完成以下检查,每一步对应相关规则:
- 数据模型 — UNIQUE(需要更新?)vs DUPLICATE(仅追加?)vs AGGREGATE(仅预聚合?)→
schema-model-choose-for-workload - 分区策略 — 时序数据?优先使用AUTO分区。小表?跳过分区。请勿同时使用AUTO和dynamic_partition。→
schema-partition-* - 分桶键+数量 — 基于JOIN键进行HASH分桶。明确计算数量:。若数据量未知,使用默认值:小维度表3个,中等表8个,大型日事实表16-32个。→
每日数据量GB / 目标Tablet大小GBschema-bucket-* - 排序键顺序 — 高选择性列优先,定长类型列在VARCHAR之前 →
schema-keys-* - 数据类型 — 使用原生类型,而非STRING。使用DECIMAL而非FLOAT。→
schema-types-* - 索引 — 等值查询用BloomFilter,文本查询用倒排索引,LIKE查询用NGram →
schema-index-* - 表属性 — 是否启用MoW?压缩配置?云模式下replication_num=1?→
schema-props-* - DDL硬约束(违反则VeloDB会拒绝DDL):
- UNIQUE KEY + PARTITION BY RANGE → 分区列必须包含在UNIQUE KEY中:
UNIQUE KEY(id, dt) PARTITION BY RANGE(dt) - 键列必须是schema中的前N列,顺序一致——键列在前,非键列在后。示例:意味着schema必须以
UNIQUE KEY(account_id, symbol)开头——切勿在键列之间插入非键列account_id, symbol, ... - 仅适用于UNIQUE MoW表——不适用于AGGREGATE或DUPLICATE表
store_row_column = "true" - AUTO分区需要 及空括号:
date_trunc()——仅列名或缺少AUTO PARTITION BY RANGE(date_trunc(col, 'day')) ()都会失败() - 动态分区需要在DDL中显式声明 子句——仅靠属性配置无效
PARTITION BY RANGE(col) () - 请勿设置 ;分桶数量仅需在
dynamic_partition.buckets中指定DISTRIBUTED BY HASH(col) BUCKETS N - 仅适用于DUPLICATE表——在UNIQUE表上会失败
compaction_policy = "time_series" - 异步MV刷新:使用 或
REFRESH AUTO ON SCHEDULE EVERY 10 MINUTE——请勿使用REFRESH COMPLETE ON SCHEDULE EVERY 10 MINUTE或REFRESH SCHEDULE EVERY。最小间隔为1分钟REFRESH ASYNC EVERY(INTERVAL ...) - MV使用/
NOW():添加CURDATE()PROPERTIES ("enable_nondeterministic_function" = "true") - BOOLEAN类型默认值必须加引号:而非
DEFAULT "true"DEFAULT TRUE - BloomFilter索引:使用 ——请勿使用内联
PROPERTIES ("bloom_filter_columns" = "col1,col2")INDEX ... USING BLOOM FILTER - AGGREGATE列语法:聚合函数在默认值之前:——而非
col BIGINT SUM DEFAULT "0"col BIGINT DEFAULT "0" SUM - AGGREGATE表的仅适用于VARCHAR类型——在INT、DATE、DECIMAL、BIGINT类型上会失败。非字符串类型使用REPLACE_IF_NOT_NULL时请省略DEFAULT:
DEFAULT "null"(而非vip_level INT REPLACE_IF_NOT_NULL)DEFAULT "null" - 是会话变量,而非表属性
enable_unique_key_partial_update - 详细信息:
schema-ddl-gotchas
- UNIQUE KEY + PARTITION BY RANGE → 分区列必须包含在UNIQUE KEY中:
2b ▸ DDL Templates (copy the closest match, customize columns)
2b ▸ DDL模板(复制最匹配的模板,自定义列)
For each CREATE TABLE, select the closest template below. Customize column names, types, bucket count, and partition settings. Do NOT write DDL from scratch.
创建表时,请选择以下最匹配的模板,自定义列名、类型、分桶数量和分区设置。请勿从零开始编写DDL。
T1: Append-only events/logs (DUPLICATE)
T1: 仅追加的事件/日志表(DUPLICATE)
sql
CREATE TABLE events (
entity_id VARCHAR(64) NOT NULL,
event_time DATETIME NOT NULL,
event_type VARCHAR(50) NOT NULL,
payload VARIANT
) DUPLICATE KEY(entity_id, event_time, event_type)
PARTITION BY RANGE(event_time) ()
DISTRIBUTED BY HASH(entity_id) BUCKETS 10
PROPERTIES (
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.start" = "-90",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"compression" = "zstd",
"compaction_policy" = "time_series",
"replication_num" = "1"
);sql
CREATE TABLE events (
entity_id VARCHAR(64) NOT NULL,
event_time DATETIME NOT NULL,
event_type VARCHAR(50) NOT NULL,
payload VARIANT
) DUPLICATE KEY(entity_id, event_time, event_type)
PARTITION BY RANGE(event_time) ()
DISTRIBUTED BY HASH(entity_id) BUCKETS 10
PROPERTIES (
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.start" = "-90",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"compression" = "zstd",
"compaction_policy" = "time_series",
"replication_num" = "1"
);T2: Updatable with partition (UNIQUE MoW + CDC)
T2: 可更新带分区表(UNIQUE MoW + CDC)
sql
CREATE TABLE orders (
order_id BIGINT NOT NULL,
order_time DATETIME NOT NULL,
update_time DATETIME NOT NULL,
status VARCHAR(20),
amount DECIMAL(18,2)
) UNIQUE KEY(order_id, order_time)
PARTITION BY RANGE(order_time) ()
DISTRIBUTED BY HASH(order_id) BUCKETS 5
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"function_column.sequence_col" = "update_time",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.start" = "-365",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"replication_num" = "1"
);sql
CREATE TABLE orders (
order_id BIGINT NOT NULL,
order_time DATETIME NOT NULL,
update_time DATETIME NOT NULL,
status VARCHAR(20),
amount DECIMAL(18,2)
) UNIQUE KEY(order_id, order_time)
PARTITION BY RANGE(order_time) ()
DISTRIBUTED BY HASH(order_id) BUCKETS 5
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"function_column.sequence_col" = "update_time",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.start" = "-365",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"replication_num" = "1"
);T3: Small dimension / lookup (UNIQUE, no partition)
T3: 小维度/ lookup表(UNIQUE,无分区)
sql
CREATE TABLE dim_product (
product_id INT NOT NULL,
name VARCHAR(200),
category VARCHAR(50)
) UNIQUE KEY(product_id)
DISTRIBUTED BY HASH(product_id) BUCKETS 3
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"replication_num" = "1"
);sql
CREATE TABLE dim_product (
product_id INT NOT NULL,
name VARCHAR(200),
category VARCHAR(50)
) UNIQUE KEY(product_id)
DISTRIBUTED BY HASH(product_id) BUCKETS 3
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"replication_num" = "1"
);T4: Pre-aggregated KPIs (AGGREGATE)
T4: 预聚合KPI表(AGGREGATE)
sql
CREATE TABLE daily_kpi (
stat_date DATE NOT NULL,
dimension VARCHAR(50) NOT NULL,
metric_sum BIGINT SUM DEFAULT "0",
metric_max DOUBLE MAX DEFAULT "0",
unique_users BITMAP BITMAP_UNION
) AGGREGATE KEY(stat_date, dimension)
PARTITION BY RANGE(stat_date) ()
DISTRIBUTED BY HASH(dimension) BUCKETS 3
PROPERTIES (
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "MONTH",
"dynamic_partition.start" = "-12",
"dynamic_partition.end" = "1",
"dynamic_partition.prefix" = "p",
"replication_num" = "1"
);sql
CREATE TABLE daily_kpi (
stat_date DATE NOT NULL,
dimension VARCHAR(50) NOT NULL,
metric_sum BIGINT SUM DEFAULT "0",
metric_max DOUBLE MAX DEFAULT "0",
unique_users BITMAP BITMAP_UNION
) AGGREGATE KEY(stat_date, dimension)
PARTITION BY RANGE(stat_date) ()
DISTRIBUTED BY HASH(dimension) BUCKETS 3
PROPERTIES (
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "MONTH",
"dynamic_partition.start" = "-12",
"dynamic_partition.end" = "1",
"dynamic_partition.prefix" = "p",
"replication_num" = "1"
);T5: Point query / API serving (UNIQUE MoW + row store)
T5: 点查询/API服务表(UNIQUE MoW + 行存储)
sql
CREATE TABLE user_profiles (
user_id BIGINT NOT NULL,
update_time DATETIME NOT NULL,
name VARCHAR(100),
data VARIANT
) UNIQUE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 5
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"function_column.sequence_col" = "update_time",
"store_row_column" = "true",
"light_schema_change" = "true",
"replication_num" = "1"
);sql
CREATE TABLE user_profiles (
user_id BIGINT NOT NULL,
update_time DATETIME NOT NULL,
name VARCHAR(100),
data VARIANT
) UNIQUE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 5
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"function_column.sequence_col" = "update_time",
"store_row_column" = "true",
"light_schema_change" = "true",
"replication_num" = "1"
);3 ▸ Connection & VeloCLI
3 ▸ 连接与VeloCLI
Detect VeloCLI
检测VeloCLI
Before running any queries, detect the CLI binary:
- Check env var — if set, use that binary path
VELOCLI_PATH - — use from PATH
command -v velocli - — only for explicit SelectDB environments
command -v sdbcli - If none available: fall back to client (see
mysql)references/start-*.md
运行任何查询前,请先检测CLI二进制文件:
- 检查环境变量 ——若已设置,使用该路径
VELOCLI_PATH - ——使用PATH中的可执行文件
command -v velocli - ——仅适用于明确的SelectDB环境
command -v sdbcli - 若以上均不可用: fallback至客户端(详见
mysql)references/start-*.md
When VeloCLI is available, prefer it for all operations:
若VeloCLI可用,优先使用它执行所有操作:
| Task | VeloCLI Command |
|---|---|
| Run SQL | |
| DDL inspection | |
| Table/tablet health | |
| Profile a slow query | |
| Get query profile | |
| Compare fast vs slow | |
| Performance trend | |
| Test connection | |
| Switch environment | |
| 任务 | VeloCLI命令 |
|---|---|
| 执行SQL | |
| DDL检查 | |
| 表/Tablet健康状态 | |
| 慢查询性能分析 | |
| 获取查询性能分析报告 | |
| 对比快慢查询 | |
| 性能趋势 | |
| 测试连接 | |
| 切换环境 | |
Runtime Query Investigation
运行时查询排查
For slow queries or runtime performance issues, read .
references/cli-investigation.md- Evidence first is mandatory: collect or attempt profile, tablet, DDL, stats, EXPLAIN, history, active-query, or connection evidence before forming hypotheses. If evidence cannot be collected locally, state that and provide the exact commands to run
- Prefer existing profiles: use ,
profile get <query_id>, orprofile listbefore re-executing SQLprofile history - Proactive discovery: for vague slow-query reports, start with ,
auth status, and recentprofile list --activebefore asking the user for more contextprofile list - Safety gate: before running user SQL with , check whether it is safe (no DDL, no mutation, no unbounded scan). For unknown, peak-hour, or expensive SQL, run
--profilefirst and ask confirmation or request an existing query_idvelocli sql "EXPLAIN <query>" --format json - Hypotheses, not verdicts: diagnostic mappings are heuristics. Present evidence, likely cause, what to check next, and when the conclusion may be wrong
- If velocli is unavailable, fall back to SQL commands listed in the reference
- Always use for structured agent-readable output
--format json
对于慢查询或运行时性能问题,请阅读。
references/cli-investigation.md- 必须优先收集证据:在形成假设前,先收集或尝试获取性能分析报告、Tablet信息、DDL、统计数据、EXPLAIN结果、历史记录、活跃查询或连接证据。若无法本地收集证据,请说明情况并提供具体执行命令
- 优先使用已有性能分析报告:在重新执行SQL前,先使用、
profile get <query_id>或profile listprofile history - 主动排查:对于模糊的慢查询报告,先执行、
auth status和近期的profile list --active,再向用户询问更多上下文profile list - 安全校验:使用运行用户提供的SQL前,检查是否安全(无DDL、无数据变更、无无界扫描)。对于未知、高峰时段或高成本SQL,先执行
--profile,并请求确认或获取已有的query_idvelocli sql "EXPLAIN <query>" --format json - 提出假设而非定论:诊断映射为启发式规则。请呈现证据、可能原因、下一步检查项及结论可能错误的场景
- 若velocli不可用,fallback至参考文档中的SQL命令
- 始终使用获取结构化、可被Agent读取的输出
--format json
Quick-start guides
快速入门指南
- — VeloDB Cloud
references/start-cloud.md - — Self-hosted / BYOC / on-prem
references/start-self-hosted.md
- ——VeloDB云服务
references/start-cloud.md - ——自建/BYOC/本地部署
references/start-self-hosted.md
4 ▸ Cluster Sizing
4 ▸ 集群容量规划
Sizing guides are in:
- — FE node sizing
references/sizing-fe.md - — BE sizing (integrated storage)
references/sizing-be-integrated.md - — BE sizing (cloud / storage-compute)
references/sizing-be-cloud.md - — Storage calculation formula
references/sizing-storage-formula.md
容量规划指南位于:
- ——FE节点容量规划
references/sizing-fe.md - ——BE节点容量规划(集成存储)
references/sizing-be-integrated.md - ——BE节点容量规划(云/存算分离)
references/sizing-be-cloud.md - ——存储计算公式
references/sizing-storage-formula.md
5 ▸ Rule Index by Category
5 ▸ 按类别划分的规则索引
Data Model — CRITICAL (4 rules)
数据模型 — 关键(4条规则)
- — DUP vs UNIQUE vs AGG decision tree
schema-model-choose-for-workload - — Always MoW for UNIQUE tables
schema-model-prefer-mow - — AGG cannot UPDATE/DELETE
schema-model-avoid-agg-for-updates - — Sequence column for out-of-order CDC
schema-model-sequence-col-for-cdc
- — DUP、UNIQUE、AGG选型决策树
schema-model-choose-for-workload - — UNIQUE表始终使用MoW
schema-model-prefer-mow - — AGG表无法执行UPDATE/DELETE
schema-model-avoid-agg-for-updates - — 为乱序CDC数据设置sequence列
schema-model-sequence-col-for-cdc
Partition Strategy — CRITICAL (4 rules)
分区策略 — 关键(4条规则)
- — RANGE for time-series
schema-partition-range-for-timeseries - — Dynamic partition for automated TTL
schema-partition-dynamic-ttl - — AUTO for sporadic data
schema-partition-auto-on-demand - — Skip partitioning under 1 GB
schema-partition-skip-for-small
- — 时序数据使用RANGE分区
schema-partition-range-for-timeseries - — 动态分区实现自动TTL
schema-partition-dynamic-ttl - — 零散数据使用AUTO分区
schema-partition-auto-on-demand - — 数据量小于1GB时跳过分区
schema-partition-skip-for-small
Bucket Strategy — CRITICAL (5 rules)
分桶策略 — 关键(5条规则)
- — HASH for pruning, RANDOM for DUP only
schema-bucket-hash-vs-random - — Choose high-cardinality column
schema-bucket-high-cardinality-key - — Composite key to fix data skew
schema-bucket-composite-for-skew - — Target 1-10 GB per tablet
schema-bucket-target-size - — Cloud MoW requires HASH
schema-bucket-cloud-mandatory-hash
- — 哈希分桶用于数据裁剪,随机分桶仅适用于DUP表
schema-bucket-hash-vs-random - — 选择高基数列作为分桶键
schema-bucket-high-cardinality-key - — 复合分桶键解决数据倾斜
schema-bucket-composite-for-skew - — 每个Tablet目标大小为1-10GB
schema-bucket-target-size - — 云MoW表必须使用哈希分桶
schema-bucket-cloud-mandatory-hash
Sort Key — CRITICAL (5 rules)
排序键 — 关键(5条规则)
- — High selectivity first
schema-keys-selectivity-first - — Fixed-length before VARCHAR
schema-keys-fixed-length-types - — 36 bytes max, VARCHAR terminates it
schema-keys-prefix-index-limits - — Cluster key for UNIQUE tables
schema-keys-cluster-key-for-mow - — No FLOAT/DOUBLE in sort key
schema-keys-avoid-float
- — 高选择性列优先
schema-keys-selectivity-first - — 定长类型列在VARCHAR之前
schema-keys-fixed-length-types - — 前缀索引最大36字节,VARCHAR会终止前缀索引
schema-keys-prefix-index-limits - — UNIQUE表使用集群键
schema-keys-cluster-key-for-mow - — 排序键中避免使用FLOAT/DOUBLE
schema-keys-avoid-float
Data Types — HIGH (5 rules)
数据类型 — 重要(5条规则)
- — Native types, not STRING
schema-types-native-vs-string - — JSON/ARRAY disable ZoneMap
schema-types-zonemap-limitations - — VARIANT for semi-structured JSON
schema-types-variant-json - — BITMAP_UNION for exact count-distinct
schema-types-bitmap-count-distinct - — DATETIME precision, VARCHAR vs STRING
schema-types-doris-specifics
- — 使用原生类型,而非STRING
schema-types-native-vs-string - — JSON/ARRAY类型会禁用ZoneMap
schema-types-zonemap-limitations - — 半结构化JSON使用VARIANT类型
schema-types-variant-json - — BITMAP_UNION实现精确去重计数
schema-types-bitmap-count-distinct - — DATETIME精度、VARCHAR vs STRING
schema-types-doris-specifics
Indexes — HIGH (7 rules)
索引 — 重要(7条规则)
- — BloomFilter for equality
schema-index-bloomfilter - — Inverted for text/range
schema-index-inverted - — NGram for LIKE %pattern%
schema-index-ngram-for-like - — Bitmap for medium cardinality
schema-index-bitmap - — HNSW/IVF for ANN search
schema-index-vector - — Full-text MATCH + BM25
schema-index-text-search
- — 等值查询使用BloomFilter
schema-index-bloomfilter - — 文本/范围查询使用倒排索引
schema-index-inverted - — LIKE %pattern%查询使用NGram
schema-index-ngram-for-like - — 中等基数列使用Bitmap索引
schema-index-bitmap - — 近似最近邻搜索使用HNSW/IVF
schema-index-vector - — 全文检索使用MATCH + BM25
schema-index-text-search
Query Acceleration — HIGH (3 rules)
查询加速 — 重要(3条规则)
- — Sync MV for single-table aggregation
schema-mv-sync-rollup - — Async MV for multi-table JOIN
schema-mv-async-join - — Operational limits (50M rows, 3 concurrent)
schema-mv-async-limits
- — 单表聚合使用同步MV
schema-mv-sync-rollup - — 多表JOIN使用异步MV
schema-mv-async-join - — 操作限制(5000万行、3个并发)
schema-mv-async-limits
Table Properties — HIGH/MEDIUM (2 rules)
表属性 — 重要/中等(2条规则)
- — Cloud mode forced properties
schema-props-cloud-forced - — LZ4 vs ZSTD compression
schema-props-compression
- — 云模式强制属性
schema-props-cloud-forced - — LZ4 vs ZSTD压缩
schema-props-compression
Caching — MEDIUM (2 rules)
缓存 — 中等(2条规则)
- — File cache for cloud mode
schema-cache-file-cache - — Query and partition cache
schema-cache-query-partition
- — 云模式下的文件缓存
schema-cache-file-cache - — 查询与分区缓存
schema-cache-query-partition