0

我們有一個表格,其中有超過62k行。我們正在運行就可以了很簡單的刪除查詢其需要45分鐘才能完成:Postgres緩慢運行刪除查詢

DELETE FROM myTable WHERE createdtime < '2017-03-07 05:00:00.000' 

的事情,我們曾嘗試:

1加時間戳列的索引,這並沒有幫助。

2-使用函數刪除了批次爲20或50的行,該函數仍然非常慢。

3-刪除了引用該表的所有外鍵約束和它自己的主鍵約束,這有助於減少時間到幾秒鐘,但我們無法安全地在生產數據庫上執行此操作,因爲它會鎖定表,並防止事務正在運行時讀寫。

我不認爲這個查詢花了很長時間才能完成是正常的。任何建議表示讚賞。

+5

'刪除引用此表的所有外鍵約束'這些FK的索引是否支持它們(在* other *表上)? – joop

+0

他說什麼。很明顯,花在查找FK約束上的時間是 – paqash

+0

性能問題應該包括EXPLAIN ANALYZE以及關於表大小,索引,當前時間性能,期望時間等的一些信息。慢是一個相對項,我們需要真正的值來比較。 MySQL也請閱讀[如何 - 問](http://stackoverflow.com/help/how-to-ask) – e4c5

回答

3

... Dropped all the foreign key constraints referencing this table

確保這些FK的指標都支持他們(另表)。 刪除時,(級聯)FK將必須檢查其他表中可能引用此行的所有FK列。


- 例如:

CREATE TABLE team(
     id INTEGER NOT NULL PRIMARY KEY 
     , name varchar UNIQUE 
     ); 

CREATE TABLE player(
     id INTEGER NOT NULL PRIMARY KEY 
     , team_id integer REFERENCES team(id) 
     , name varchar UNIQUE 
     ); 

現在,如果一個team被刪除,FK約束則要檢查是否有有關本team_id任何球員。 (和級聯appropiately) 在這種情況下,在FK支持性指標將有助於DBMS:

CREATE index ON player(team_id); 

將有助於是有點太弱了這裏。對於每一個非平凡的案例,絕對需要一個支持性指數。 (即使FK約束有ON UPDATE NO ACTION ON DELETE NO ACTION作爲它的動作,所以它似乎)

+0

爲了每個人的利益,即使我的FKs都設置爲ON UPDATE NO ACTION DELETE NO ACTION,但這個檢查似乎已經發生,導致查詢運行緩慢,這對我來說是令人驚訝的。 – infiniteLoop

+0

@infiniteLoop:這根本就不奇怪,因爲數據庫需要確保沒有玩家引用你正在刪除的「團隊」。如果沒有索引,那麼查找基本上是使用'select * from player'來完成的,其中team_id = ...',這將需要播放器表上的Seq掃描。 –

+0

@a_horse_with_no_name:但爲什麼需要這樣做呢?檢查它是否打算刪除與被刪除父行關聯的子行? – infiniteLoop