【问题标题】:How to optimize delete older records after the first N records?如何优化删除前 N 条记录后的旧记录?
【发布时间】:2021-10-19 19:43:37
【问题描述】:

我在工作中使用postgres,并且有一个表queries 使用btree 作为pkey 索引

TABLE queries (
  id serial
  ... other fields
)

我们有一个查询想要删除比前 N 个元素更旧的元素,查询看起来像这样,$1N

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 是我们唯一要比较的东西?或者有一个不同的查询来实现我最初的目标?

【问题讨论】:

  • 我们可以使用更多关于该表及其索引的信息。请read this 然后edit 你的问题。

标签: sql postgresql query-optimization


【解决方案1】:

你需要EXPLAIN (ANALYZE, BUFFERS)来查看时间花在了哪里(小心,它会执行DELETE)。

执行计划看起来很合理,如果您遇到少至 500000 行的问题,我敢打赌该表被 foreign keys that are not indexed 引用。

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 2018-11-09
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    相关资源
    最近更新 更多