【发布时间】: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 一起用于我的后端服务。请注意,我不想截断并插入此表,因为有许多用户并行操作相同的数据。我检查了多个关于这个问题的帖子,尝试了所有可能的选项。
这是我测量延迟的方式:
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