【发布时间】:2021-10-19 19:43:37
【问题描述】:
我在工作中使用postgres,并且有一个表queries 使用btree 作为pkey 索引
TABLE queries (
id serial
... other fields
)
我们有一个查询想要删除比前 N 个元素更旧的元素,查询看起来像这样,$1 是 N。
DELETE FROM queries
WHERE id < COALESCE(
(
SELECT min(id)
FROM (
SELECT id
FROM queries
ORDER BY id DESC
LIMIT $1
) ids
),
0
);
此查询的EXPLAIN 结果是
Delete on queries (cost=174908.32..322825.71 rows=272064 width=6)
InitPlan 1 (returns $0)
-> Aggregate (cost=174908.31..174908.32 rows=1 width=8)
-> Limit (cost=0.42..168658.31 rows=500000 width=8)
-> Index Only Scan Backward using queries_pkey on queries queries_1 (cost=0.42..275314.52 rows=816191 width=8)
-> Seq Scan on queries (cost=0.00..147917.39 rows=272064 width=6)
Filter: (id < COALESCE($0, '0'::bigint))
在我们的 PROD 环境中使用N = 5e5,此查询需要相当长的时间。有一个seq扫描,但我真的不知道它来自哪里,也不知道如何优化它。 id 上不是已经有索引了吗,而且似乎id 是我们唯一要比较的东西?或者有一个不同的查询来实现我最初的目标?
【问题讨论】:
标签: sql postgresql query-optimization