Postgres 10:查询有限制的时间范围分区会导致所有分区扫描

问题描述 投票:0回答:1

为了简单起见,我有一个包含 2 列的表,

customer_id
是 int,
created_at
是时间戳。我为
created_at
创建了基于范围的分区,因此每个分区都保存一天。我还有一个索引(customer_id,created_at DESC)。然后我运行查询:

SELECT * FROM my_table WHERE customer_id = 123 ORDER BY created_at DESC LIMIT 10

该查询运行速度非常慢。

EXPLAIN ANALYZE
表示 postgres 实际上是从匹配 WHERE 子句的所有分区中选择行,然后对它们进行排序,然后才返回前 10 个。这是预期的行为吗?在这种情况下,获得前 10 条记录的更好方法是什么?感觉就像用不同的
created_at
值重试直到达到所需的记录数量是有点错误的方法。但我可能是错的。

sql postgresql postgresql-10
1个回答
0
投票

PostgreSQL 必须扫描每个分区以检查是否有

customer_id = 123
的行,然后应用 ORDER BYcreated_at DESC 和 LIMIT 10。问题是 PostgreSQL 没有充分利用分区来停止扫描。足够的行。

为了提高性能,您可以尝试以下策略:

使用约束排除和分区剪枝

SHOW constraint_exclusion;

如果设置为关闭,请启用它:

SET constraint_exclusion = partition;

优化索引

您可以尝试更有针对性的索引。仅针对 customer_id 的复合索引和针对created_at 的单独索引可能会有所帮助:

CREATE INDEX idx_customer_created_at ON my_table (customer_id, created_at DESC);
© www.soinside.com 2019 - 2024. All rights reserved.