Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Как оптимизируются триггеры?
|
|||
|---|---|---|---|
|
#18+
DB2 v9.1.2 Express-C Есть четыре таблицы: организации, ее договоры страхования, полисы сотрудников по этим договорам, и собственно сотрудники. Соответственно имеются первичные и внешние ключи. Для каждой таблицы написал триггеры выполняющие элементарные проверки (на допустимость символов и т.п.). В триггерах AFTER UPDATE выполняю запись в отдельные таблицы (аналогичные исходным) истории изменений. CREATE TRIGGER USRSCHEMA.UPDAF_ORG AFTER UPDATE ON USRSCHEMA.ORGANIZATIONS REFERENCING OLD AS OLDROW NEW AS NEWROW OLD_TABLE AS OLDTABLE NEW_TABLE AS NEWTABLE FOR EACH ROW MODE DB2SQL BEGIN ATOMIC -- запись в историю -- INSERT INTO USRSCHEMA.ORGANIZATIONS_JN (ххх) VALUES (ххх); END@ Теперь хочу реализовать каскадное изменение таблиц - к примеру, при изменении статуса организации соответственно меняются записи всех дочерних таблиц. Решил сделать это также в триггере AFTER UPDATE. Делаю так: CREATE TRIGGER USRSCHEMA.UPDAF_ORG AFTER UPDATE ON USRSCHEMA.ORGANIZATIONS REFERENCING OLD AS OLDROW NEW AS NEWROW OLD_TABLE AS OLDTABLE NEW_TABLE AS NEWTABLE FOR EACH ROW MODE DB2SQL BEGIN ATOMIC IF NEWROW.ORG_STA_ID=-1 THEN UPDATE USRSCHEMA.CONTRACTS SET CON_STA_ID=-1, CON_OPR_ID=NEWROW.ORG_OPR_ID WHERE CON_ORG_ID=OLDROW.ORG_ID; DELETE FROM USRSCHEMA.CONTRACTS WHERE CON_STA_ID=-1; ELSE IF NEWROW.ORG_STA_ID=0 THEN UPDATE USRSCHEMA.CONTRACTS SET СON_STA_ID=0, CON_OPR_ID=NEWROW.ORG_OPR_ID WHERE CON_ORG_ID=OLDROW.ORG_ID; END IF; END IF; -- запись в историю -- INSERT INTO USRSCHEMA.ORGANIZATIONS_JN (ххх) VALUES (ххх); END@ Для других таблиц триггеры аналогичные. При этом получаю жуткие тормоза, БД требует под компиляцию запроса UPDATE ORGANIZATIONS SET ORG_STA_ID=-1 WHERE ORG_ID=1 море памяти, план запроса показывает что-то невообразимое - тьма FILTER и ТABLE SCAN (индексы по полям участвующим в кляузе WHERE имеются). Если же реализацию логики перенести в ХП - то все работает без проблем. Но хотелось бы это сделать именно триггером - полагаю так более правильно. Помогите понять логику оптимизатора, что я тут принципиально не так делаю. Возможно есть другой способ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2009, 14:17 |
|
||
|
Как оптимизируются триггеры?
|
|||
|---|---|---|---|
|
#18+
askfinder, Триггеры оптимизируются вместе (т.е. как одно целое) с командой, которая породила действия, обрабатываемые триггерами. В чём смысл такой последовательности: UPDATE USRSCHEMA.CONTRACTS SET CON_STA_ID=-1 , CON_OPR_ID=NEWROW.ORG_OPR_ID WHERE CON_ORG_ID=OLDROW.ORG_ID; DELETE FROM USRSCHEMA.CONTRACTS WHERE CON_STA_ID=-1 ; ? Вы удаляете строку, которую предыдущей командой изменили. Это действительно надо? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2009, 09:47 |
|
||
|
Как оптимизируются триггеры?
|
|||
|---|---|---|---|
|
#18+
Mark Barinstein, Дело в том, что в триггерах AFTER DELETE происходит запись в историю изменений (т.к. запись из регулярной таблицы может быть удалена в результате как очистки - DELETE, так и при изменении статуса на -1 - такие требования в условии задачи, а запись в историю нужна для определения в результате чего таки была удалена запись). В результате экспериментов вынес операции UPDATE и DELETE в ХП (практически копи/паст) и вызываю их из триггера. Стало работать в разы быстрее (по ощущениям - примерно на порядок). Но не вполне понятно почему. Т.к. условия в WHERE не менялись, сами операции вставки-удаления тоже по-сути те же, то не похоже, что проблема в отсутствии индексов/статистики или в конфигурации БД и т.п.. Думаю, что - в особенностях построения плана оптимизатором или непосредственно в выполнении. А т.к. производительность отличается весьма существенно, то разница должна быть принципиальной. Вот это я и хочу понять - в чем собственно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2009, 11:24 |
|
||
|
Как оптимизируются триггеры?
|
|||
|---|---|---|---|
|
#18+
Посмотри планы запросов. Может многое станет ясно. Возможно время убивается на компиляцию? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2009, 12:39 |
|
||
|
Как оптимизируются триггеры?
|
|||
|---|---|---|---|
|
#18+
askfinder, Если у вас ORGANIZATIONS.ORG_ID не меняется update'ом, то можно попробовать триггер на statement, а не на каждую строку. Типа: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2009, 18:50 |
|
||
|
Как оптимизируются триггеры?
|
|||
|---|---|---|---|
|
#18+
Mark Barinstein, Попробовал разные варианты (Ваш в т.ч.) на тестовых таблицах (три десятка записей в таблице сотрудников). Получил следующее: 1. Вариант - исходный, только изменил DELETE FROM USRSCHEMA.CONTRACTS WHERE CON_STA_ID=-1 на DELETE FROM USRSCHEMA.CONTRACTS WHERE CON_STA_ID=NEWROW.ORG_ID (первичный ключ из ORGANIZATIONS) Результат: 660 попугаев затрат, время выполнения UPDATE (примерное) - 19 сек. 2. Ваш вариант - 492 попугая затрат, время выполнения UPDATE (примерное) - 19 сек. 3. Вариант с вызовом из триггера ХП (в которой UPDATE и DELETE) - 53 попугая затрат, время выполнения UPDATE (примерное) - 2 сек. Решил пока остановиться на третьем варианте (хотя не скажу, что он мне нравится) но нет уверенности что при росте объема данных производительность резко не упадет. gardenman, Планы выполнения для вариантов 1 и 2 схожи - масса объединений, GENROW, FILTER и TBSCAN (всего узлов в плане около 7-8 десятков, IXSCAN присутвует ближе к вершине дерева). Для варианта 3 - план значительно проще (полагаю, из-за наличия уже построенных планов ХП). Начинаю подозревать что именно поэтому (использование уже построенных ранее планов "как есть") база работает быстрее - много затрат уходит на построение плана для триггера (он строится при каждом вызове или все-таки нет?). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2009, 11:05 |
|
||
|
|

start [/forum/topic.php?fid=43&msg=35980548&tid=1603260]: |
0ms |
get settings: |
6ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
| others: | 222ms |
| total: | 362ms |

| 0 / 0 |
