2016-11-22 97 views
1

当我运行这行代码时。当我在Postgres中删除一些记录时,查询运行时间过长

DELETE from monthlyevaluatedbudgettable where budgetforyear = 2018; 

它只是说在状态栏Query is Running.,我认为它不会结束,所以我会取消它,然后在错误日志的消息此警告后:

ERROR: canceling statement due to user request 
CONTEXT: SQL statement "DELETE FROM ONLY "public"."monthlyadjustedbudgettable" WHERE $1 OPERATOR(pg_catalog.=) "budgetid"" 

********** Error ********** 

ERROR: canceling statement due to user request 
SQL state: 57014 
Context: SQL statement "DELETE FROM ONLY "public"."monthlyadjustedbudgettable" WHERE $1 OPERATOR(pg_catalog.=) "budgetid"" 

monthlyadjustedbudgettable的关系是ON DELETE CASCADEmonthlyevaluatedbudgettable。有人能告诉我会有什么问题吗?

我在这两个表中都有182,095记录。他们的关系是one-to-one

+0

两张桌子有多大? –

+0

约182,095条记录。但是当我使用budgetforeyar = 2018时,它将返回60,751条记录。 – msagala25

+0

对不起先生。 @TimBiegeleisen,但你能解释一下什么索引先生。我不明白。谢谢。对小菜很抱歉。 – msagala25

回答

1

您应该首先尝试在当前查询上使用EXPLAIN以查看详细信息。

我的预感,为什么你的删除查询是如此之慢,你有一个ON DELETE CASCADE约束monthlyadjustedbudgettable。这意味着对于monthlyevaluatedbudgettable中的每个记录,必须在monthlyadjustedbudgettable中进行检查以确定是否还有需要删除的记录。由于该表没有索引,所以可能发生全表扫描。鉴于你在每张表中都有大约20万条记录,这在时间上可能会非常大。

有一个快速修复,你可以尝试。您可以在monthlyadjustedbudgettable外键列上添加索引:

CREATE UNIQUE INDEX budget_idx ON monthlyadjustedbudgettable (budgetid); 

这里假定monthlyadjustedbudgettable外键列被称为budgetid

+0

我不知道它是如何发生的,但它真的有效。谢谢先生。 @Tim Biegelsen。请帮我理解这是如何工作的。我在查询中遇到了很多这样的问题。你能告诉我更多关于你为什么使用索引。哈斯我不相信它,我非常高兴。谢谢。 1投票和正确的答案。 – msagala25

+0

我的回答我不清楚吗? –

+0

这就好像当monthlyevaluatedbudgettable中的1条记录被删除时,当它逐级记录到monthlyadjustedbudgettable时,它会一一检查所有182,095条记录吗?但是当你有索引时,它会搜索相同的预编码,它会结束?对不起我。我英语不太好。 :) – msagala25