我有一个像这样的 QuestDB 表:
CREATE TABLE 'trades' (
symbol SYMBOL,
side SYMBOL,
price DOUBLE,
amount DOUBLE,
timestamp TIMESTAMP,
ingestion_time TIMESTAMP
) timestamp (timestamp) PARTITION BY DAY WAL;
有数亿行。这些行按照多年的时间划分。我尝试做一个像这样的简单查询:
SELECT ingestion_time, count() from trades
WHERE ingestion_time BETWEEN '2024-01' AND '2024-02'
SAMPLE BY 1d
但是查询速度很慢。当我查看日志时,似乎打开了许多不在此时间范围内的分区。我认为通过给出一个时间范围,它只会读取该范围内的数据而不是所有内容?
我该如何解决这个问题?
QuestDB 有“指定时间戳”的概念,它对应于表的排序。如果您使用此时间戳进行查询,那么 QuestDB 将使用间隔扫描并避免接触不在该范围内的分区。如果您使用 EXPLAIN
运行查询,您会看到这种低效的过滤:
Row forward scan
,即全表扫描。然后它会过滤掉
ingestion_time
。这是因为,当您使用 timestamp
子句创建表时,您将指定时间戳设置为
ingestion_time
,而不是 timestamp (timestamp)
。
您应该使用 timestamp
列进行时间过滤,或使用 ingestion_time
作为排序时间戳重新创建表。如果您使用 EXPLAIN
运行以下查询:
SELECT ingestion_time, count() from trades
WHERE timestamp BETWEEN '2024-01' AND '2024-02'
SAMPLE BY 1d
filter: null
),而数据库在指定的时间范围内使用
Interval forward scan
。这将执行得更快,并且只触及所需的数据。