2013-04-08 3 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

Иногда можно добавить новые разделы: создать новую таблицу, в которой 'INHERITS' родительская таблица, добавить соответствующее ограничение, заполнить ее, создать на ней индексы. Это работает только тогда, когда ваши новые данные могут быть четко разделены на одно ограничение. –

+0

Это больше похоже на проблему ввода-вывода памяти или диска. Строки 150K не являются огромным количеством - возможно, вам просто нужно выделить больше памяти для postgres? Даже тогда, насколько велика таблица. Для чтения всех этих данных с диска требуется не один час. – AngerClown

ответ

1

Попробуйте NOT EXISTS вместо NOT IN, как:

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

Кроме того, если newfiles заполняется каждый раз с нуля, убедитесь, что вы ANALYZE newfiles перед выдачей любого запроса, который использует его, так что оптимизатор может работать с хорошая статистика.

Если это не помогло, попробуйте EXPLAIN или EXPLAIN ANALYZE по вашим запросам, чтобы иметь план выполнения и добавить его в вопрос.

+0

Извините, что полностью забыл, что я спросил об этом здесь ... -_- – alphatiger

+0

Это очень помогло, на самом деле для каждого запроса требуется менее одной секунды. После того, как вы попытались использовать оба варианта, это помогло использовать 'NOT EXISTS' вместо' NOT IN'. спасибо! – alphatiger

Смежные вопросы