【问题标题】:Slower delete from smaller parent table [duplicate]从较小的父表中删除速度较慢[重复]
【发布时间】:2021-11-04 18:24:15
【问题描述】:

在我的应用程序中,我从 PostgreSQL 数据库中的子表和父表中删除。我按以下顺序删除:

DELETE FROM answers_reports_t WHERE event_reports_id in (
                    SELECT id FROM events_reports_t WHERE recall_id = :recallId)"

DELETE FROM events_reports_t WHERE recall_id = :recallId

answers_reports_t是一个子表,其外键event_reports_id引用父表的events_reports_t.id

多个答案属于一个事件,大小比约为 3:1。目前,answers_reports_t 有 280K 行,events_reports_t 95K。

我注意到 delete #2 始终比 delete #1 慢,尽管差异很小。这是来自应用程序的日志。

ANSWERS Delete: 41ms
EVENTS  Delete: 58ms
ANSWERS Delete: 41ms
EVENTS  Delete: 59ms
ANSWERS Delete: 41ms
EVENTS  Delete: 67ms

索引如下。

我对性能的预期正好相反。另外,是否有可能以某种方式结合这个父子删除,以进一步优化性能?

【问题讨论】:

  • 你试过ON DELETE CASCADE吗?
  • 您是否有理由避免级联约束?例如,请参阅Delete rows and other rows with a reference to the deleted row。约束可能也是它变慢的原因,因为父表上的删除必须检查依赖表。
  • 谢谢会试一试。 CASCADE 的名声很危险,我被告知要谨慎使用它。
  • 检查explain (analyze) delete ...的输出如果FK检查由于缺少索引而变慢,我不会感到惊讶。

标签: sql postgresql


【解决方案1】:

另外,是否有可能以某种方式结合这个父子删除,以进一步优化性能?

是的,可以使用 data-modifying CTE 在单个语句中执行此操作,但我怀疑它的速度要快得多

with report_delete as (
   DELETE FROM events_reports_t 
   WHERE recall_id = 2
   returning id
)
DELETE FROM answers_reports_t 
WHERE event_reports_id in (select id from report_delete);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 2010-12-08
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多