Ухудшение производительности при обновлении таблиц с 10 -х миллионов записей

dba.stackexchange https://dba.stackexchange.com/questions/17653

Вопрос

Я хочу обновить таблицы (My Be 20-30), имея по 10 миллионов записей каждый.

Проблема в том, что для процесса обновления требуется слишком много времени, а также в то время использование ЦП также очень высока. Я хочу сделать так, чтобы он не мог использовать много процессора при обработке данных. Если время обработки увеличено, то это не будет проблемой для меня, но оно должно использовать ограниченные ресурсы ЦП для обработки (обновления) таблицы. Я использую PostgreSQL в качестве операционной системы базы данных, а сервер - Linux.

Пример моего запроса может быть таким

UPDATE TEMP 
SET CUSTOMERNAME = 
  ( select customername from user where user.customerid = temp.customerid );
Это было полезно?

Решение

Первый вопрос: почему важно, чтобы вы не использовали много процессора? Запрос будет узким местом немного ресурс; Если бы вы могли ввести достаточно дополнительного доступа к диску, время, используемое процессором в секунду, упадет, но это действительно улучшит? Какой ресурс вы бы предпочли насыщать? Понимание того, почему вы подчеркнули, что это может помочь людям предоставить ответ, который вы найдете полезным.

Как предполагается в комментарии, ваш запрос может работать быстрее с соединением, а не с коррелированным подразделением. Что-то вроде этого:

UPDATE temp
  SET customername = user.customername
  FROM user
  WHERE user.customerid = temp.customerid;

Еще одна важная вещь, которую нужно знать, хотите ли вы обновить все строки в таблице. Некоторые из значений уже верны? Если это так, вы получите большой повышение производительности, не обновляя ряды, которые не нуждаются в этом. Добавлять AND temp.customername is distinct from user.customername в WHERE пункт.

Если вы ограничиваете количество строк, обновленных в каждом операторе, и VACUUM ANALYZE После каждого обновления вы избежите раздувания таблицы. Если смысл желания минимизировать время процессора состоит в том, чтобы избежать влияния на производительность на одновременные транзакции, это даст вам возможность ввести короткую задержку (в форме sleep или что -то подобное), прежде чем начать следующее UPDATE набора рядов.

Более того, почему вы избыточно сохраняете информацию в таблице температуры, а не присоединяетесь к ней, когда это необходимо? (Иногда есть веская причина; довольно часто нет.)

Другие советы

Если вы следовали очень хорошему совету Kgrittn и все еще имеете проблемы с производительностью, вам может потребоваться выполнить обновление партиями. Вы все равно будете выполнять обновления на основе наборов, но ограничить их первыми 1000 (или любое количество, что и для вас, я использовал от 500 до 50 000) записей, которые не совпадают, а затем продолжают цикть, пока все не будут сделаны.

Если есть индекс на TEMP.CUSTOMERNAME и вы обновляете значительную часть TEMP Таблица затем бросьте этот индекс перед обновлением и восстановите его после.

PostgreSQL не может сократить количество времени процессора, которое может использовать процесс. На Linux вы можете использовать функции ОС, такие как Ренис команда сделать это. Видеть Приоритеты Для получения дополнительной информации и некоторых образцов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top