【问题标题】:Fastest way to execute a delete query in large table in PostgreSQL在 PostgreSQL 的大表中执行删除查询的最快方法
【发布时间】:2021-01-09 11:58:04
【问题描述】:

我有一个大表和一个简单的删除查询,从表中删除 13k 条匹配记录大约需要 84 秒。以下是迄今为止测试的 JPA 查询。

delete from PlanItems p where p.jobId = :jobid

测试的其他变体:

delete from PlanItems p where p.jobId in (select pi.jobId from PlanItems pi where pi.jobId = :jobid)

鉴于表PlanItems 已经在列jobId 上定义了一个索引,并且该表中只有一个外键,有哪些选项可以加快我的删除查询?我将postgres 与spring jpa 一起用于我的后端服务。请注意,我不想截断并插入此表,因为有许多用户并行操作相同的数据。我检查了多个关于这个问题的帖子,尝试了所有可能的选项。

查询执行计划详情: 查询 1-> 查询 2->

这是我测量延迟的方式:

long start = System.currentTimeMillis();
planItemsRepository.deleteByJobId(jobId);
end = System.currentTimeMillis();
log.info("Took around "+(end-start)+" milliseconds to delete all plan items records by jobId "+jobId);

并且存储库逻辑如下所示:

@Transactional
@Modifying
@Query(value = "delete from PlanItems p where p.jobId in (select pi.jobId from PlanItems pi where pi.jobId = :jobid) ")
int deleteByJobId(@Param("jobid") long jobId);

我想知道如何将延迟降低到一半甚至更短。

【问题讨论】:

  • 如果是后台作业,则尝试分块删除数据。如果您有诸如 added_date 或 modified_date 之类的列,则根据日期过滤数据,否则先获取 1000 或 500 行的 ID,然后将其删除,依此类推。
  • 其他表是否在属于外键约束的列上有索引?请注意,在询问查询性能时,最好包含所有相关的 DDL 和 explain analyze 的输出。
  • 也许 other 表有这个 planitems 表的外键?
  • @wildplasser 另外两个表具有planitems 表的外键。但这些都是小桌子。
  • @Eelke 是的,该表在同一列上也有索引。我只关心这里的删除操作。我记录了延迟以进行验证。

标签: sql spring postgresql spring-boot spring-data-jpa


【解决方案1】:

如果此查询需要很长时间:

delete from PlanItems p where p.jobId = :jobid

并且您在PlanItmes(jobId) 上有一个索引——其中jobId 是索引中的第一列——那么您需要考虑其他问题。

  1. 是否存在使用jobId 的级联外键约束?如果是这样,级联可能会影响这些表 - 如果它们是级联删除,那么删除这些行可能会影响更多表。

  2. 表上有删除触发器吗?如果是这样,您的“简单”删除可能比您想象的要多得多。

  3. 系统负载过重吗?如果是这样,时间可能只是在等待删除行的机会。

  4. 物化视图是建立在桌子上的吗?如果是这样,它们可能正在被刷新。

如果这些都不是,那么这可能是您如何测量经过时间的问题。

【讨论】:

  • 感谢您的回复。我正在浏览您的 cmets,我在上面的帖子中更新了更多详细信息。
猜你喜欢
  • 2010-10-27
  • 1970-01-01
  • 2016-11-26
  • 2010-09-09
  • 1970-01-01
  • 2011-01-20
  • 2010-10-17
  • 2015-06-10
  • 2010-11-23
相关资源
最近更新 更多