Сообщение здесь на DBA.StackExchange ( Каковы лучшие практики для триггеров для поддержания номера ревизии в записях? ) Породило интересный (по крайней мере, интересный для меня) вопрос относительно производительности в MySQL.
Контекст заключается в том, что мы хотим вставить запись в таблицу для каждой обновляемой строки. Перед обновлением строки мы хотим сохранить предыдущее значение, а затем увеличить один из столбцов (столбец «версия»).
Если мы сделаем это внутри триггера, это сработает хорошо. Для MySQL триггеры строка за строкой , так что это было бы простым решением. Выберите данные, которые в данный момент находятся в таблице, вставьте их в таблицу журналов и обновите столбец «версия» в новых данных.
Однако возможно переместить эту логику в хранимую процедуру. Если вы сделаете это, вы выполняете вставку, а затем увеличиваете столбец «версия» в таблице. Вся вещь будет установлена на основе.
Итак, когда дело доходит до выполнения этой вставки, будет ли более целесообразным использовать подход хранимых процедур на основе множеств или подход, основанный на триггерах?
Этот вопрос касается MySQL (поскольку он имеет построчные триггеры), хотя он может применяться к другим построчным триггерным СУБД.
Ответы:
Для простоты триггеры - это способ реализации любого вида отслеживания изменений в базе данных. Тем не менее, вы должны знать, что происходит под капотом при использовании триггеров.
Согласно программированию хранимых процедур MySQL , страница 256 под заголовком «Служебная нагрузка триггера» говорит следующее:
Подробное объяснение затрат на запуск приведено на страницах 529-531. Заключительный вывод из этого раздела гласит следующее:
Не упоминается в книге еще один фактор при использовании триггеров: когда дело доходит до ведения журнала аудита, имейте в виду, что вы вводите данные. Я говорю это потому, что если вы решите войти в таблицу MyISAM, каждый INSERT в таблицу MyISAM производит полную блокировку таблицы во время INSERT. Это может стать серьезным узким местом в среде с большим трафиком и высокой транзакцией. Кроме того, если триггер работает с таблицей InnoDB, и вы регистрируете изменения в MyISAM изнутри триггера, это тайно отключит соответствие ACID (т. Е. Уменьшит количество транзакций блока до поведения автоматической фиксации), которое нельзя откатить.
При использовании триггеров на таблицах InnoDB и регистрации изменений
Таким образом, журналы аудита могут извлечь выгоду из COMMIT / ROLLBACK, как и основные таблицы.
Что касается использования хранимых процедур, вам придется кропотливо вызывать хранимую процедуру в каждой точке DML для отслеживаемой таблицы. Можно легко пропустить регистрацию изменений в виде десятков тысяч строк кода приложения. Размещение такого кода в триггере исключает поиск всех этих операторов DML.
ПРЕДОСТЕРЕЖЕНИЕ
В зависимости от того, насколько сложным является триггер, он все еще может быть узким местом. Если вы хотите уменьшить количество узких мест в журнале аудита, есть кое-что, что вы можете сделать. Однако это потребует небольшого изменения инфраструктуры.
Используя аппаратное оборудование, создайте еще два Сервера БД
Это позволит серверу сократить количество операций ввода-вывода при записи в основную базу данных (MD) благодаря ведению журнала аудита. Вот как вы можете это сделать:
Шаг 01) Включите бинарное ведение журнала в основной базе данных.
Шаг 02) Используя недорогой сервер, настройте MySQL (той же версии, что и MD) с включенным двоичным журналированием. Это будет марка. Настройка репликации с MD на DM.
Шаг 03) Используя второй недорогой сервер, настройте MySQL (ту же версию, что и MD) с отключенным бинарным ведением журнала. Настройте каждую таблицу аудита для использования --replicate-do-table . Это будет АС. Настройка репликации от DM до AU.
Шаг 04) mysqldump структуры таблицы из MD и загрузки ее в DM и AU.
Шаг 05) Преобразуйте все таблицы аудита в MD, чтобы использовать механизм хранения BLACKHOLE
Шаг 06) Конвертируйте все таблицы в DM и AU, чтобы использовать механизм хранения BLACKHOLE
Шаг 07) Преобразуйте все таблицы аудита в AU, чтобы использовать механизм хранения MyISAM
Когда сделано
Это позволяет хранить информацию аудита на отдельном сервере БД, а также уменьшает любое ухудшение операций ввода-вывода при записи, которое обычно имеет MD.
источник
Вот подход, чтобы выполнить это обновление оптом.
Для этого примера
Чтобы создать table_A_Keys2Update, сделайте следующее:
После заполнения table_A_Keys2Update идентификаторами, номера ревизий которых необходимо увеличить, выполните следующее ОБНОВЛЕНИЕ ОБНОВЛЕНИЯ, чтобы увеличить номер ревизии всех строк, идентификатор которых содержится в table_A и table_A_Keys2Update:
Этот однострочный запрос может заменить триггер и хранимую процедуру.
При желании вы можете поместить этот запрос в хранимую процедуру и вызывать его, если хотите.
источник