性能调优技巧
GreptimeDB 实例的默认配置可能不适合所有场景。因此根据场景调整数据库配置和使用方式相当重要。
性能调优不仅限于服务器配置。表结构和索引设计会直接影响写入和查询效率。有关主键、append-only 表与去重表、索引选择、表布局和分区的指导,请参阅设计表结构。
GreptimeDB 提供了各种指标来帮助监控和排查性能问题。官方仓库里提供了用于独立模式和集群模式的 Grafana dashboard 模版。
查询
分析查询性能
要排查慢查询,请使用 EXPLAIN ANALYZE VERBOSE 重新运行查询:
EXPLAIN ANALYZE VERBOSE <SQL>;
EXPLAIN ANALYZE 会执行查询并采集各执行阶段的运行时指标。VERBOSE 选项会增加 scan 级别的指标,有助于判断查询变慢的原因以及可以如何优化。输出中各项指标的含义请参阅 EXPLAIN。
比较多次运行结果时,请注意缓存状态可能影响第二次运行的耗时和结果。如果想避免测量完全命中缓存的重复查询,可以在保持查询形态等价的前提下稍微修改查询条件,例如平移时间范围。
如果仍无法判断原因,请在创建 issue 时附上完整的 EXPLAIN ANALYZE VERBOSE 输出。
常见发现:
- 需要搜索大量小文件:
num_file_ranges较高,尤其是许多文件不足一个完整 row group 时,通常表示扫描需要打开大量小 SST 文件。这往往来自对大量不同时间窗口的回填,或 compaction 压力较高。可以考虑调整compaction.twcs.time_window,检查写入或回填模式,让行更自然地填满时间窗口,并检查 compaction 状态。如果文件数量不多,小文件不一定会影响性能。 - 扫描后过滤了大量行:如果
scan_cost较高且rows_precise_filtered也较高,说明扫描读取了大量候选行,然后又通过精确过滤移除了它们。请参阅添加索引以提升过滤性能。 - 数据读取时本地缓存未命中:如果
fetch_metrics.cache_miss、fetch_metrics.pages_to_fetch_store或fetch_metrics.store_fetch_elapsed较高,说明 GreptimeDB 正在从对象存储读取 page 数据,而不是从本地缓存读取。请检查下文的缓存指标,并考虑增大write_cache_size或page_cache_size。 - 扫描准备成本较高:
build_parts_cost或build_reader_cost较高,表示 GreptimeDB 花了较多时间构建扫描范围或 reader。请结合num_file_ranges、元数据缓存未命中以及缓存压力一起分析。 - 元数据加载时间较高:如果
metadata_cache_metrics.metadata_load_cost或metadata_cache_metrics.cache_miss较高,可能是 SST 元数据缓存过小。请检查greptime_mito_cache_bytes{type="sst_meta"},并考虑增大sst_meta_cache_size。
添加索引以提升过滤性能
索引可以减少 GreptimeDB 需要读取和过滤的数据量。如果 EXPLAIN ANALYZE VERBOSE 显示 scan_cost 较高且 rows_precise_filtered 很多,请将查询中的 WHERE 谓词与表结构进行比较。经常用于选择性过滤,且未被主键前导列覆盖的列,是较好的索引候选列。
请根据查询和列选择索引类型:
- 对低基数列上的过滤条件(包括等值、范围和
IN谓词)使用倒排索引。 - 对 trace ID 和 request ID 等高基数列上的等值过滤使用跳数索引。
- 对非结构化文本搜索使用全文索引。
索引会占用存储和内存,并可能增加 flush 和 compaction 延迟,因此不要为每一列都创建索引。有关索引如何补充主键排序以及如何选择索引类型,请参阅表设计指南中的索引。有关索引语法和管理方式,请参阅数据索引。
添加索引后,请使用 EXPLAIN ANALYZE VERBOSE 重新运行同一查询,并比较 scan_cost 和 rows_precise_filtered。索引裁剪也会体现在对应索引类型的 rg_*_filtered 和 rows_*_filtered 计数器中。目前,新添加的索引仅对新 flush 的数据生效:后续 flush 生成 SST 文件时会为其构建索引,但不会为已有 SST 文件添加索引。
指标
以下指标可用于诊断查询性能问题:
| 指标 | 类型 | 描述 |
|---|---|---|
| greptime_mito_read_stage_elapsed_bucket | histogram | 存储引擎中查询不同阶段的耗时。 |
| greptime_mito_cache_bytes | gauge | 缓存内容的大小。type 标签表示缓存类型。 |
| greptime_mito_cache_hit | counter | 缓存命中总数。type 标签表示缓存类型。 |
| greptime_mito_cache_miss | counter | 缓存未命中总数。type 标签表示缓存类型。 |
| greptime_mito_cache_eviction | counter | 缓存淘汰总数。type 标签表示缓存类型。 |