2012-12-12 22 views
3

我有一個表之間的關係,都與一個'所有者'表有關。所以只是爲了舉例起見:爲什麼ON DELETE CASCADE有時在Postgres 9上花費很長時間?

  • 表所有者與PK ID
  • 父表與PK ID和FK owner_id指Owner.id,上面有一個索引,並ON DELETE CASCADE
  • 表兒童與PK ID和FK PARENT_ID指Parent.id,上面有一個索引,並ON DELETE CASCADE

Child表是巨大的(約5000萬行),Parent表有幾千行,Owner表非常小(~10行)。

還有一些其他表與Owner和Parent相關,但它們相對較小(幾千),並且在外鍵上也有索引,並且ON CASCADE DELETE

有時當我刪除所有者行通過刪除所有(約1200萬個行和千個父行)級聯的作品真快(幾秒鐘),但有時需要近一個小時。

如何找出造成這種情況的原因? >位圖索引掃描和索引掃描 - 我的delete from child where parent_id in (select id from parent where owner_id = 1),其中1是所有者行之一的ID(我試過各種IDS只是爲了確保),它是說,它使用位圖堆掃描做explain。但是我不確定是否模仿了ON DELETE CASCADE觸發器時實際做了什麼。我怎樣才能找出造成這些巨大延誤的原因?難道有時Postgres更喜歡進行順序掃描(由於行數)?

插入相同的行只需要8分鐘(包括應用程序邏輯和幾千事務提交),所以我不明白,爲什麼直刪除正在採取這麼長時間。

我使用的Postgres 9.1.6

+1

請嘗試解釋ANALYZE –

+0

嘗試解釋分析從parent_id在parent_id(從父母其中owner_id = 1),並得到相同的位圖堆掃描 - >位圖索引等孩子刪除了這些成本:(成本= 150.01。 .562757.84行= 6560827寬度= 12)(實際時間= 39.792..39.792行= 0的循環= 1) – jbx

+0

有可怕的錯誤統計數據 - 因此位圖索引掃描是不是最優的 - 請,嘗試禁用bitmap_scan - 「設置enable_bitmapscan關閉「 –

回答

0

你說,有時從秒變爲小時。有相當多的行被刪除。您可能正在處理各種因素,從數據緩存到行鎖。不幸的是,如果這些是暫時的情況,當它不發生時可能很難追蹤它們。

你應該看看最初有幾件事情是你是否能找到任何模式發生這種情況時,是否SELECT * FROM pg_lock,當它發生。當問題發生時,您應該也會看到SELECT * FROM pg_stat_activity,以查看可能正在鎖定的位置。

+0

沒有鎖,沒有其他人正在訪問數據庫。 (事實上​​,我有時只是刪除數據庫來清理數據,因爲刪除它需要很長時間,並且允許我)。是的,有大量的行,但插入它們需要8分鐘,所以刪除它們花費數小時是沒有意義的。我最近增加了'shared_buffers'和'effective_cache_size'的默認值,這似乎有一些影響,把它降低到20分鐘左右...更好,但不確定它的最優。 – jbx