2013-04-08 103 views
1

我使用數據庫來表示文件列表以及與它們中的每一個相關的一些元數據。我需要定期更新此文件列表,只添加新文件並刪除不再存在的文件(我不必觸摸表格中的現有行,因爲我會丟失相關的元數據)。postgresql中的高效增量插入

我目前的查詢只需要幾秒鐘,當我有大約10000個文件,但我的當前150000文件表需要一個小時。

在互聯網上經過一番研究,我一直在以下過程:

  1. 填充表 「newfiles」 與掃描
  2. DELETE FROM files WHERE path NOT IN (SELECT path FROM newfiles);
  3. INSERT INTO files (SELECT * FROM newfiles WHERE path NOT IN (SELECT path FROM files));

的結果我也有索引:

CREATE INDEX "files_path" ON "files" ("path"); 
CREATE INDEX "files_path_like" ON "files" ("path" varchar_pattern_ops); 
CREATE INDEX "files_path" ON "newfiles" ("path"); 
CREATE INDEX "files_path_like" ON "newfiles" ("path" varchar_pattern_ops); 

(我主要使用這些索引在數據庫中搜索;我的應用程序在文件中有一個搜索引擎。)

當我有150000個文件時,這兩個查詢都需要一個多小時。 我該如何優化?

謝謝。

+0

有時候可行的​​選擇是添加新分區:創建一個新表,在其中插入一個父表,添加一個適當的約束,填充它,在其上創建索引。這隻適用於您的新數據可以在單個約束條件下明確分區的情況。 – 2013-04-08 10:52:21

+0

這聽起來更像是內存或磁盤IO問題。 150K行不是一個巨大的數量 - 也許你只需要分配更多的內存給postgres?即便如此,桌子有多大。從磁盤讀取所有這些數據不需要一個小時。 – AngerClown 2013-04-08 12:32:48

回答

1

嘗試NOT EXISTS而不是NOT IN,如:

DELETE FROM files WHERE NOT EXISTS 
    (SELECT 1 FROM newfiles WHERE newfiles.path=files.path); 

此外,如果newfiles是每次都從頭開始填充,確保您ANALYZE newfiles發佈使用它的任何查詢,以便優化程序可以工作之前很好的統計。

如果這樣不能解決問題,請在您的查詢上嘗試EXPLAINEXPLAIN ANALYZE以制定執行計劃並將其附加到問題中。

+0

對不起,我完全忘記了這個問題...... -_- – alphatiger 2013-05-01 21:57:28

+0

這非常有幫助,實際上現在每個查詢只需不到一秒。 嘗試這兩個選項後,它使用'NOT EXISTS'而不是'NOT IN'來幫助。 非常感謝! – alphatiger 2013-05-01 22:04:18