Из-за MVCC-модели Postgres и в соответствии с правилами SQL, UPDATE
записывает новую версию строки для каждой строки, которая не исключена в WHERE
предложении.
Это делает имеют более или менее существенное влияние на производительность, прямо и косвенно. «Пустые обновления» имеют ту же цену за строку, что и любое другое обновление. Они запускают триггеры (если они есть), как и любое другое обновление, они должны быть зарегистрированы в WAL, и они генерируют мертвые строки, раздувающие таблицу и вызывающие дополнительную работу на VACUUM
потом, как и любое другое обновление.
Записи индексов и столбцы TOASTed, в которых не изменен ни один из задействованных столбцов, могут остаться прежними, но это верно для любой обновленной строки. Связанный:
Это почти всегда хорошая идея, чтобы исключить такие пустые обновления (когда есть реальный шанс, что это может произойти). Вы не предоставили определение таблицы в своем вопросе (что всегда является хорошей идеей). Мы должны предположить, что first_name
может иметь значение NULL (что не удивительно для «имени»), поэтому в запросе необходимо использовать NULL-безопасное сравнение :
UPDATE users
SET first_name = 'Michael'
WHERE id = 123
AND first_name IS DISTINCT FROM 'Michael';
Если first_name IS NULL
до обновления тест с just просто first_name <> 'Michael'
оценивается как NULL и как таковая исключает строку из обновления. Подлая ошибка. Если столбец определенNOT NULL
, используйте простую проверку на равенство, потому что это немного дешевле.
Связанный: