PostgreSQL индекс не используется после больших вставок - PullRequest
0 голосов
/ 27 марта 2020

У меня есть приложение, которое должно обрабатывать «большой» объем данных: первый шаг - это временная загрузка данных в таблицу из файла CSV (в описанном случае около 1,7 миллиона строк), а второй - обработка обновлений. / вставляет в другую таблицу на основе загруженных данных посредством одного запроса:

UPDATE destination_table d
SET ...
FROM temp_table t
WHERE d.column = t.column;

Примечание: temp_table очищается после полного завершения процесса

У нас были некоторые проблемы с производительностью поскольку в t.column отсутствовал индекс (процесс postgres использовал 100% ЦП, и запрос мог зависнуть на несколько часов и даже дней), мы добавили его, и запрос «только» выполнялся примерно через 5 минут это спецификация c в нашей среде, которая более чем приемлема.

Проблема, с которой я сталкиваюсь, заключается в том, что в клиентских средах (то же число RAM / vCPU) индекс, похоже, не используется. В одном из них приложение, похоже, работало, но сейчас мы сталкиваемся с той же проблемой (запрос зависает на несколько дней с процессом, использующим 100% ЦП) для одного и того же файла.

После некоторой проверки я заметил что индекс не был отсканирован в их среде

В нашем pg_stat_all_indexes говорит мне для этого индекса, что:

  • idx_scan: 2060888
  • idx_tup_read: 3762435
  • idx_tup_fetch: 3762432

в их окружении:

  • idx_scan: 6
  • idx_tup_read: 6
  • idx_tup_fetch: 6

Я говорил с кем-то об этом, и он сказал мне, что причина может заключаться в том, что после вставок таблица не была очищена пылесосом. Процесс был запущен 23/03 в их среде (все еще "запущен" ...), и когда я смотрю на last_autovacuum на temp_table, это было сделано 20/02 (не 03), только один раз, очевидно, так как autovacuum_count равен "1". Он сказал мне, что мы должны «накачать» вакуум в процессе эксплуатации, но поскольку вставки в таблицу и обновление должны быть последовательными, я не понимаю, как это может работать.

Вопросы:

  • Обязателен ли вакуум (анализ?) Каждый раз, когда я загружаю данные в свою таблицу temp_table, чтобы мой индекс правильно использовался при выполнении следующего обновления?
  • Чем можно объяснить разницу сканирования индекса между средами?

1 Ответ

0 голосов
/ 27 марта 2020

когда я смотрю на last_autovacuum на temp_table, это было сделано 20/02 (не 03), только один раз, очевидно, так как autovacuum_count равен "1".

Я не думал, что временные столы когда-либо были автоматически убраны. Это фактическая таблица TEMP, или постоянная таблица, из которой вы вручную удаляете строки?

Он сказал мне, что мы должны "накачать" вакуум в процессе эксплуатации, но как вставки в таблицу и обновление должно быть последовательным, я не понимаю, как оно может работать.

Я не понимаю проблемы. Вставьте оператор VACUUM ANALYZE temp_table между операторами INSERT и UPDATE. (Или, может быть, просто АНАЛИЗ).

Обязателен ли вакуум (анализ?) Каждый раз, когда я загружаю данные в свою таблицу temp_table, чтобы мой индекс правильно использовался при выполнении следующего обновления?

Да, анализ АНАЛИЗ обязательно, если вы хотите, чтобы запрос планировался с использованием правильной статистики. Конечно, это не гарантирует, что он будет использовать тот план, который вам нужен.

Чем можно объяснить разницу сканирования индекса между средами?

Вероятно, выше, но, видя результат «EXPLAIN (ANALYZE, BUFFERS)», когда он не использует индекс, определенно может помочь его закрепить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...