Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Собственно говоря тест был мною проведен для определения, насколько использование триггеров по сравнению с DEFAULT LAST USER и DEFAULT TIMESTAMP при UPDATE будет отличаться по скорости выполнения (можно сказать родился с другого форума). Для теста я взял ASA 9.0.2.2551, создал новую БД с 8кб страницей, выделил 132 мб памяти под кэш, процессор Atlon XP2500, ОС XP SP2. Вот скрипт теста: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 00:27 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Пасиб. Не забуду при случае ответить тем же ;-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 01:41 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Если будет возможность, хотелось бы увидеть результаты прогона этого теста на FB2 - я специально не ставил на DML блокировку всей таблицы или изоляцию 3, чтобы ASA поднапряглась с PRIMARY KEY на позаписных блокировках. Интересно узнать, как быстро этот "тупой" тест выполнится на версионнике FB для расширения своего ликбеза. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 01:51 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Меня вот больше интересует другое. Если таблица с LAST USER и TIMESTAMP реплицируется, то что попадет в эти поля после прихода изменений из удаленной базы? Боюсь, что будет имя, под которым dbremote работает. Если это так, то плохо и пригодно только для нереплицируемых таблиц. А при использовании триггера этим легко управлять. Собираюсь проверить на досуге. О результатах сообщу. -- http://talk.ru/forum/talk.ru.accounting.development ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 01:57 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Итак, имеем сервер Firebird WI-T2.0.0.10269 Alpha 1. Для теста создана новая БД с ODS 11.0 и размером страницы 8кб. Для базы установлен страничный кеш в 20К страниц (160МБ), все остальные настройки дефолтные. Режим изоляции транзакций - ReadCommitted. Железо - ноутбук Toshiba с CPU P-4 3.06GHz, RAM 512MB. ОС - WinXP Prof SP1. Все апдейты выполнялись трижды, время бралось последнее. После каждого апдейта выполнялась сборка мусора, чтобы устранить кооперативную сборку на время замера. Без этого время всех апдейтов, кроме первого, можно удваивать. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. Даже если бы FB и поддерживал обсуждаемую фичу, то дальнейшие тесты все равно выглядели бы как-то бесперспективно ;-) И я еще говорил о 20%... мдя. В общем, можно смело сказать, что это "бессмысленно, как безалкогольное пиво". Спасибо за внимание ;-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 02:50 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
ASCRUSИз чего следует вывод, что на скорость выполнения DML оператор DEFAULT не влияет. Если же посмотреть на скорость обновления миллиона записей с установленным триггером, то видна разница почти в 2 раза по сравнению с чистым UPDATE. Так что можно смело сказать, что LAST USER и TIMESTAMP здорово экономят время выполнения UPDATE на больших обьемах данных. Спасибо за внимание :)Можно я тоже влезу ? :) IMHO тест показывает огромные накладные расходы ASA на вызов триггера. Дабы проверить это печальное предположение, предлагаю упростить триггер до пустого блока и повторить тест. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 10:02 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
hvladIMHO тест показывает огромные накладные расходы ASA на вызов триггера. Дабы проверить это печальное предположение, предлагаю упростить триггер до пустого блока и повторить тест. Упрощать нет смысла, результат вполне предсказуем. Я не верю, чтобы пара присваиваний работала в два раза дольше аналогичного дефолта. С этой стороны действительно обсуждаемая фича имеет заметное преимущество перед решением на основе триггера. Но переносить это на другие СУБД все же не стоит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 10:16 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Решил этот же тест прогнать на рабочей машине, заодно поиграться с блокировками. На рабочей машине стоят SATA винты и процессор Intel P4 2,4 (HT - получается 2 процессора, оба разрешены для использования в ASA). В итоге: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. Следующий вывод - BEFORE триггера, изменяющие записи, гораздо тяжелее, чем не делающие это. Кстати я тоже в этом не сомневался, так как могу точно сказать, что ASA крутит WatcomSQL c космической скоростью (взять хотя бы мой написанный на нем компилятор MacroSQL или на его основе написанный просмоторщик клипперных программ, загружающий их в БД, с преобразованием их скрипты в виде HTML веб-сервиса с подсветкой перехода на функции и таблицы для просмотра в браузере с целью снятия головной боли разбора чужих исходников на Clipper 5.0). Я думаю в данном случае при изменении записей в триггерах тормозит сама архитектура работы ASA, так как судя по всему порядок выполнения DML осуществляется в порядке для каждой записи: 1. DEFAULT 2. Блокировка 3. BEFORE FOR EACH ROW Триггера 4. CHECK 5. FOREIGN KEY 6. Физ.опер.записи в страницу, лог и индексы 7. SYSTEM CASCADE FOR EACH ROW Триггера 8. AFTER FOR EACH ROW Триггера Схема приведена упрощенная, например, те же CASCADE могут вызываться по опции не как AFTER, а как BEFORE. С моей точки зрения кстати схема достаточно эффективная, так как любой BEFORE TRIGGER может вызвать исключение и произойдет откат изменений только всех успевших измениться записей (и блокировок тоже), а не всего массива записей, соотвествующе и откат произойдет быстрее. Тормоза же с триггерами думаю можно обьяснить не сколько замедлением выполнения из за выполнения WatcomSQL, сколько расширенным выделением ресурсов на выполнение триггеров, стоит помнить, что в ASA есть область видимости локальных временных таблиц, глобальных переменных и прочих фич, которые тоже напрягают сервер, да и выделение записных переменных или таблиц в REFERENCING тоже надо думать не прибавляет скорости. Общий вывод - в FB2 триггеры работают гораздо шустрее, в ASA на массовые операции во многих случаях лучше вешать AFTER TRIGGER FOR EACH STATEMENT. P.S. Кстати вопросик к dimitr - массовые вставки конечно же лучше проводить через специальные команды или утилиты (bcp, LOAD TABLE и т.д.). Как с этим обстоят дела у FB2 ? Например в ASA миллионы записей грузяться через LOAD TABLE достаточно шустро, эта команда не организует блокировок и работает на CHECKPOINT, как в принципе и REORGINIZE TABLE - кстати эти обе команды навевают на мысль, что CHECKPOINT в ASA (который позволяет БД работать и без лог-файла) подозрительно напоминает версионные принципы работы :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 11:19 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Интересно, ASCRUS, что ты столько сил потратил на доказательство того, что вполне очевидно : дефолт - это чисто декларативная штука, серверу это сделать легко, а триггер - его же выполнять надо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 11:21 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
ASCRUSСледующий вывод - BEFORE триггера, изменяющие записи, гораздо тяжелее, чем не делающие это. 50 сек против 54 сек? Я бы не назвал это "гораздо тяжелее". Достаточно ожидаемая разница. ASCRUSОбщий вывод - в FB2 триггеры работают гораздо шустрее, в ASA на массовые операции во многих случаях лучше вешать AFTER TRIGGER FOR EACH STATEMENT. IMHO тут все же играет роль WatcomSQL, каким бы шустрым он не был. А именно его интеграция в ядро сервера. В FB нет различия между SQL и PSQL, первое - это просто подмножество второго, оба являются нативным кодом и выполняются в ядре. Т.е. вызов триггера - это рекурсия в интерпретатор дерева выполнения плюс два копирования (из записи в OLD и из NEW в запись). Ну и создание сэйвпойнта, конечно. ASCRUSP.S. Кстати вопросик к dimitr - массовые вставки конечно же лучше проводить через специальные команды или утилиты (bcp, LOAD TABLE и т.д.). Как с этим обстоят дела у FB2 ? Эксклюзивных режимов массовой вставки (чтобы сэкономить на блокировках, версиях и прочая) нет в принципе, как нет и утилит. Предлагается штатный механизм т.н. внешних таблиц, которые представляют собой бинарные файлы со строками фиксированной длины. Они к базе отношение имеют только через метаданные, работают вне контроля транзакций. Имея такую таблицу, далее делаем просто INSERT INTO <database table> SELECT * FROM <external table>. Механизм достаточно удобный, но пока что не ахти какой быстрый (неоптимальная реализация - нет multi-block reads). Будет улучшено (читай: ускорено) в следующих версиях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 11:40 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
MasterZivвполне очевидно: дефолт - это чисто декларативная штука, серверу это сделать легко, а триггер - его же выполнять надо. Что русскому хорошо, то немцу смерть (с) ;-) Я оспорил данную очевидность и доказал свою правоту на отдельно взятом сервере. Если брать именно "выполнение" триггера, то его код между парой begin/end полностью идентичен паре дефолтов. Затраты появляются именно из-за "подготовки окружения" (за неимением лучшего термина) вызова триггера. А насколько они велики - зависит от СУБД. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 11:51 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
авторИнтересно, ASCRUS, что ты столько сил потратил на доказательство того, что вполне очевидно : дефолт - это чисто декларативная штука, серверу это сделать легко, а триггер - его же выполнять надо. Иногда очевидные вещи вдруг оказываются не очевидными. Я в ASA уже с этим сталкивался после опыта работы с MSSQL, думая что очевидное в MSSQL так же очевидно в ASA. Поэтому предпочитаю все проверять, благо что сил особо много прикладывать не приходиться :) Например совсем недавно я провел собственное исследование по блокировкам в различных уровнях изоляции и могу сказать, что BOL читать полезно, а вот все ручками тестировать позволяет понять архитектуру сервера на низком уровне и при проектировнии БД учитывать ньюансы механизма блокировок ASA. Один наглядный пример - пока я не повозился с BEFORE триггерами по поводу обновления полей записей и не выложил команде ASA парочку багов, в BOL не слова не было сказано об этих возможностях. После выхода патча по моим багам заодно дописали и BOL :) То же в принципе и касается использования промежуточных переменных в UPDATE (каюсь, во многом по моей вине, исправив мои замечания по багам здесь, они намутили кучу багов с UPDATE на remote server и мне все думалось - чего это я так часто икаю) :) P.S. В принципе у меня есть еще в запасе парочка багов, которые можно найти, только очень постаравшись, но так как ситуация с ними маловероятна, я их не выкладываю в CASE, появится кто-то, кто в практическом использовании на них натыкался, тогда и нужно будет исправлять :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 12:10 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Александр ГoлдунМеня вот больше интересует другое. Если таблица с LAST USER и TIMESTAMP реплицируется, то что попадет в эти поля после прихода изменений из удаленной базы? Боюсь, что будет имя, под которым dbremote работает. Если это так, то плохо и пригодно только для нереплицируемых таблиц. Проверил только что. Работает абсолютно корректно - просто пересылается апдейт этих полей с нужными значениями. А я по привычке использовал триггера с проверкой IF CURRENT REMOTE USER IS NULL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 13:42 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Александр ГoлдунМеня вот больше интересует другое. Если таблица с LAST USER и TIMESTAMP реплицируется, то что попадет в эти поля после прихода изменений из удаленной базы? Боюсь, что будет имя, под которым dbremote работает. Если это так, то плохо и пригодно только для нереплицируемых таблиц. А при использовании триггера этим легко управлять. Я уже проверял :) Приходит то что и должно прийти. В репликации, упоминаются все поля в которых изменилось значение. Если эти значения изменились под действием DEFAULT, то вот эти новые значения и пойдут в удаленую базу. А вот если они были сделаны триггером и репликация работает в режиме активных триггеров - в поле Last_user ты получишь имя юзера под которым к базе подключился dbremote. Так что DEFAULT LAST USER со всех точек зрения, намного лучше триггера :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 18:23 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
White Owl Так что DEFAULT LAST USER со всех точек зрения, намного лучше триггера :) За исключением случая, когда используется справочник юзеров и вместо логина varchar ставится код integer. А вот насчет TIMESTAMP однозначно удобнее ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2005, 18:37 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
White OwlТак что DEFAULT LAST USER со всех точек зрения, намного лучше триггера :) К сожалению не со всех. Мне все-таки пришлось делать триггер, чтобы реализовать функциональность "скрытого update" (я писал об этом в топике Значение по умолчанию для столбца ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.02.2005, 08:19 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
White Owl Александр ГoлдунМеня вот больше интересует другое. Если таблица с LAST USER и TIMESTAMP реплицируется, то что попадет в эти поля после прихода изменений из удаленной базы? Боюсь, что будет имя, под которым dbremote работает. Если это так, то плохо и пригодно только для нереплицируемых таблиц. А при использовании триггера этим легко управлять. Я уже проверял :) Приходит то что и должно прийти. В репликации, упоминаются все поля в которых изменилось значение. Если эти значения изменились под действием DEFAULT, то вот эти новые значения и пойдут в удаленую базу. А вот если они были сделаны триггером и репликация работает в режиме активных триггеров - в поле Last_user ты получишь имя юзера под которым к базе подключился dbremote. Так что DEFAULT LAST USER со всех точек зрения, намного лучше триггера :) Вот я и наступил на грабли с LAST USER в репликации :( Если запись правится новым пользователем, то LAST USER отлично срабатывает, изменения корректно реплицируются в удаленную базу. А вот при повторной правке записи тем же пользователем, в посылаемом сообщении в UPDATE отсутствует упоминание поля с LAST USER. За то в таком случае на удаленной базе срабатывает LAST USER и прописывает юзера от dbremote. Придется возвращать обратно триггера - они корректно такие вещи отрабатывали, даже в режиме активных триггеров. Просто нужно блок обрамить проверкой IF CURRENT REMOTE USER IS NULL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2005, 13:45 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
это явный глюк. Я с этим игрался еще на семерке - все было в порядке. Сейчас проверим... и будем писать в саппорт :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.05.2005, 19:59 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
White Owl пишет: > это явный глюк. Я с этим игрался еще на семерке - все было в порядке. > Сейчас проверим... и будем писать в саппорт :) Почему глюк? По моему корректное и логично объясняемое поведение: Если пользоватетель тот же, то LAST USER фактически не изменияет поле => изменение не попадает в лог => изменение не попадает в сообщение На принимающей стороне dbremote производит UPDATE других полей, не задевая поле с LAST USER => срабатывает LAST USER и выставляет значение в логин от dbremote. Где изъян в рассуждениях? Posted via ActualForum NNTP Server 1.2 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.05.2005, 20:24 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Ну хорошо, не "глюк" а "фича" :) Только оно все равно не должно так работать. Прийдется делать еще одну главу в FAQ :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.05.2005, 20:52 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
Александр Гoлдун Почему глюк? По моему корректное и логично объясняемое поведение: Если пользоватетель тот же, то LAST USER фактически не изменияет поле => изменение не попадает в лог => изменение не попадает в сообщение ... Где изъян в рассуждениях? Вот здесь и изьян. LAST USER всегда изменяется - проверить легко, достаточно написать "UPDATE OF LastUser" триггер. Так что это баг или что то у Вас не так. Будет время, я тоже проверю :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.05.2005, 23:59 |
|
||
|
BEFORE TRIGGER ON UPDATE vs DEFAULT LAST USER/TIMESTAMP
|
|||
|---|---|---|---|
|
#18+
ASCRUS пишет: > Вот здесь и изьян. LAST USER всегда изменяется - проверить легко, > достаточно написать "UPDATE OF LastUser" триггер. Так что это баг или > что то у Вас не так. Будет время, я тоже проверю :) Не показатель. Если я сделаю UPDATE любого другого поля, не изменив его значения, то триггер на него тоже сработает, но в сообщение это не попадет. Проверено. Posted via ActualForum NNTP Server 1.2 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.05.2005, 09:53 |
|
||
|
|

start [/forum/topic.php?fid=55&msg=32907822&tid=2013649]: |
0ms |
get settings: |
9ms |
get forum list: |
22ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
85ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
70ms |
get tp. blocked users: |
2ms |
| others: | 257ms |
| total: | 467ms |

| 0 / 0 |
