Транзакции и уровни изоляции: где чаще всего ломают производительность
Коллеги, давайте разберем план выполнения. Транзакция — не просто «обернул в BEGIN и надеюсь». Это еще и блокировки, версия строк, ожидание I/O и риск получить красивый дедлок вместо красивого коммита.
Базовые ошибки почти всегда одни и те же: держат транзакцию открытой дольше, чем нужно; делают внутри нее тяжелый SELECT без фильтра; смешивают чтение и запись в одном блоке, хотя можно разделить. Чем дольше живет транзакция, тем больше шанс, что она начнет мешать соседям.
По уровням изоляции правило простое: повышайте только если реально видите аномалии. READ COMMITTED обычно хватает для большинства OLTP-сценариев. REPEATABLE READ и SERIALIZABLE нужны точечно, когда цена фантомов и несогласованного чтения выше, чем цена блокировок. Иначе вы лечите симптом, а не причину. Схема простая, но дьявол кроется в статистике.
Что проверять в первую очередь:
— нет ли «висячих» транзакций в приложении;
— не тянется ли в них сетевой запрос, внешний API или пользовательский ввод;
— не растут ли ожидания по lock/row lock/page lock;
— не прячется ли проблема в отсутствии индекса, из-за чего транзакция сканирует таблицу и держит блокировки дольше нормы.
Золотое правило: сначала мониторинг, потом индексы. Если видите contention — смотрите не только на запрос, но и на границы транзакции, изоляцию и порядок операций. В продакшене так лучше не делать, и вот почему: длинная транзакция почти всегда становится чужой проблемой.
Оптимизация производительности баз
@database_performance_tuning_arb
Транзакции и уровни изоляции: где чаще всего ломают производительность
Этот пост опубликован в Telegram-канале Оптимизация производительности баз. Подписаться можно по ссылке: @database_performance_tuning_arb.