UPDATE запрос

Стоимость одной строки: почему UPDATE в Delphi может оказаться дорогим
В любом приложении на Delphi, работающем с базами данных (от Access до Oracle), запрос UPDATE — это не просто команда `SET ... WHERE`. Это операция, которая имеет свою цену: прямое время выполнения, затраты на блокировки, сетевой трафик и скрытые расходы на повторную синхронизацию клиентского кэша. Если смотреть на это с точки зрения бюджета разработки и эксплуатации, неоптимизированный UPDATE способен съесть до 30% производительности приложения.
Прямые и косвенные затраты
Прямая стоимость — это время работы сервера БД: поиск строки (особенно если нет индекса), запись журнала транзакций, обновление статистики. Косвенная стоимость проявляется в клиентской части: каждый раз после UPDATE приходится заново обновлять набор данных (DataSet.Refresh или Requery), чтобы избежать «зомби-строк» и устаревших значений. Вызов Refresh — это ещё один полный цикл SELECT, который умножает затраты на два.
Сравните цены:
- Одиночный UPDATE с WHERE по первичному ключу — минимальная цена. Индекс есть, блокировка страницы короткая.
- UPDATE без условий (или с широким WHERE) — максимум затрат. Полное сканирование таблицы, блокировка многих строк, рост лога транзакций.
- UPDATE с подзапросами или сложными выражениями в SET — скрытый расход: база вычисляет значение каждый раз, что для 10 000 строк выливается в заметное время.
Где реально экономят (и где теряют деньги)
- Пакетные UPDATE через один Execute вместо цикла — классическая экономия. Вместо 1000 отдельных вызовов SQL в цикле, один UPDATE .. FROM или временная таблица снижает сетевые задержки на 95%.
- FireDAC vs старый BDE: Переход на FireDAC (или AnyDAC) часто оправдывает свою цену за счёт встроенного кэширования изменений и пакетного режима. BDE генерирует одиночные UPDATE с проверкой timestamp, что в 3–5 раз дороже.
- Отказ от Refresh после UPDATE — опасная экономия. Можно пропустить ошибки блокировок и получить рассинхронизацию, что приведёт к дорогостоящему исправлению ошибок в production.
- Использование параметров vs строковая конкатенация — неочевидная статья расходов. При конкатенации строк каждый раз перекомпилируется план запроса. В нагрузке это даёт +40% к процессорному времени.
Скрытые расходы, о которых забывают
Первая скрытая статья — транзакции. Если каждое изменение выполняется в отдельной автоматической транзакции (AutoCommit), каждая строка оборачивается в BEGIN/COMMIT. На сервере это увеличивает дисковые операции синхронизации лога. Оптимальный вариант: группировка изменений в одну транзакцию из 100–500 записей. Экономия — до 10 раз по времени.
Вторая скрытая статья — сериализация доступа. При UPDATE с оптимистической блокировкой (проверка по всем старым полям) количество откатов (deadlock-ов) растёт в многопользовательской среде. Откат — это не просто «отмена», это ещё и перезапись лога. Старайтесь использовать UPDATE с условием только по первичному ключу и версии строки (timestamp).
Третья статья — размер передаваемых данных. Если обновляете поле VARCHAR(4000), а нужно изменить только один символ, вы всё равно отправляете полное содержимое. В современных СУБД (PostgreSQL, MS SQL) это не так критично, но для Firebird/Interbase размер пакета влияет на скорость.
Практическая ценность для Delphi-разработчика
На проектах с тысячами одновременных UPDATE (ERP, складские системы) выбор правильной стратегии определяет финальную стоимость владения (TCO). Даже в небольших утилитах стоит избегать:
- UPDATE в триггерах (каскадные обновления — дорого и запутанно);
- полная перезапись всех полей, когда нужно изменить одно;
- использование UpdateMode=upWhereAll (FireDAC) без крайней необходимости.
Хорошая новость: в 2026 году даже недорогие хостинги баз данных (DigitalOcean, VDS) позволяют аптайм 99.9%, но цена запросов всё ещё ложится на разработчика. Грамотный UPDATE — это такой же инструмент экономии, как выбор лицензии СУБД или количества ядер сервера.
В итоге: измеряйте время выполнения UPDATE в ваших тестовых сценариях, группируйте транзакции, используйте первичные ключи и параметры — и ваш проект останется в бюджете.
Добавлено: 27.04.2026
