2016-11-22 123 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