|
31.03.2007, 15:17 | #1 |
Участник
|
тупость при удалении из InventJournalTrans
удаляли сегодня инвентаризационный журнал,я громко матюкался когда обнаружил этот тупняк (88000 строк журнала удалялось 4 часа).
итак таблица: InventJournalTrans X++: void delete() { ; ttsbegin; appl.inventUpdateTTSControl().setTTSBeginLock(); super(); if (this.journalType == InventJournalType::Count) InventItemLocation::updateStopCountingJournal(this); InventUpd_DeleteMovement::newMovement(InventMovement::construct(this)).updateNow(); if (this.voucher) { if (this.numOfVoucherLines() == 0) // нас интересует эта строка !!! JournalError::deleteVoucher(tableNum(InventJournalTable),this.journalId,this.voucher); } appl.inventUpdateTTSControl().setTTSCommitLock(); ttscommit; } X++: Integer numOfVoucherLines() { return (select forceplaceholders count(recId) from inventJournalTrans index hint VoucherIdx where inventJournalTrans.journalId == this.journalId && inventJournalTrans.voucher == this.voucher).recId; } X++: // SHiSHok 20070331 boolean voucherLineExist() { return (select firstfast firstonly forceplaceholders recId from inventJournalTrans index hint VoucherIdx where inventJournalTrans.journalId == this.journalId && inventJournalTrans.voucher == this.voucher).recId != 0; } void delete() { ; ttsbegin; appl.inventUpdateTTSControl().setTTSBeginLock(); super(); if (this.journalType == InventJournalType::Count) InventItemLocation::updateStopCountingJournal(this); InventUpd_DeleteMovement::newMovement(InventMovement::construct(this)).updateNow(); if (this.voucher) { // if (this.numOfVoucherLines() == 0) // if (!this.voucherLineExist()) JournalError::deleteVoucher(tableNum(InventJournalTable),this.journalId,this.voucher); } appl.inventUpdateTTSControl().setTTSCommitLock(); ttscommit; }
__________________
--- SHiSHok |
|
|
За это сообщение автора поблагодарили: mazzy (5), belugin (6), kashperuk (3), konopello (2), fialka (1), bobski (1). |
10.02.2010, 18:24 | #2 |
Участник
|
ну, собственно, в 4-й версии таким широким жестом проверяется наличие строк для удаления (метод Delete()) в следующих таблицах:
InventJournalTrans ProdJournalBOM ProdJournalProd ProdJournalRoute ProjJournalTrans TutorialJournalTrans (sic! чему нас учат!) более нигде этот волшебный метод numOfVoucherLines не вызывается.
__________________
Felix nihil admirari |
|
10.02.2010, 18:56 | #3 |
Участник
|
Хоть и было, это давно, но все же спрошу, а действительно ли прирост был в 6 раз, ну или хотя бы в 2 или 3 раза ?
Действительно, подсчет строк не самый, наверное, лучший вариант для определения, есть ли записи в таблице или нет, но замечу, что во всех таблицах, на которых есть этот волшебный метод, присутствует индекс VoucherIdx, в состав, которого входят оба поля, так что подсчет количества строк должен быть сравним с поиском первой записи по времени, по крайней мере для повторных запросов. Да, на тестовой выдало время 35 мин, а дальше, что ? Думаю, если подождать эти 35 минут, то Progress Bar будет показывать уже совсем другое время (проверял, будет показывать другие числа, на DAX 4.0 (виртуальная машина от MS) ). На мой взгляд, проблема того, что строки удаляются долго, в том, что все они удаляются в одной транзакции. Безусловно, при проверке на существование одной записи прирост производительности операции удаления будет, но не в разы.
__________________
Sergey Nefedov |
|
10.02.2010, 19:05 | #4 |
Moderator
|
Стоит помнить, что для складских журналов можно настроить режим, при котором один ваучер выделяется не на строку, а на все строки с одинаковой датой . Для этого случая - гипотеза о сопоставимости времени выполнения count() и загрузки одной строки не срабатывает...
Да и в режиме Номенклатура+дата, выделение нового ваучера происходит только если в очередной строке номенклатура отличается от номенклатуры в предыдущей строке. Если у тебя, скажем, списывается много одинаковой номенклатуры с разными серийными номерами - гипотеза тоже не срабатывает. |
|
10.02.2010, 19:06 | #5 |
Участник
|
да, мне тоже показался прирост совсем незначительным. на 2500 записях я никакого прироста не ощутил. но методы поправил.
кстати, вопрос методологический: а зачем вообще удалять строки из инв. журнала?
__________________
Felix nihil admirari |
|
10.02.2010, 22:52 | #6 |
Участник
|
А смысл разносить фактическое нувое количество если по системе также 0?
|
|
10.02.2010, 22:54 | #7 |
Участник
|
а поразвёртнутей можно? я не компетентен в вопросе настолько, чтоб из вопроса на вопрос составить себе ответ.
__________________
Felix nihil admirari |
|
10.02.2010, 20:57 | #8 |
Участник
|
Как раз наоборот. Много мелких транзакций в цикле выполняются заметно дольше, чем одна общая транзакция на весь цикл. Время тратится на отдельное открытие-закрытие каждой мелкой транзакции.
|
|
10.02.2010, 21:32 | #9 |
Administrator
|
... но при этом на больших объемах данных и при многопользовательской работе это ставит БД колом на время выполнения транзакции. Хотя формально получается быстрее (аналогично тому, что цикл с прогресс-баром крутится медленнее, чем без него, но при этом психологически кажется что быстрее)
__________________
Возможно сделать все. Вопрос времени |
|
11.02.2010, 11:15 | #10 |
Участник
|
Цитата:
Также могут начать возникать блокировки чтения (правда зависит от версии системы и уровня изоляции при чтении - READ_COMMITTED_SNAPSHOT в SQL 2005 говорят проблему эту решает) И если транзакция будет длится, скажем, 4 часа, но через 3:59 выключат свет в серверной , то после перезагрузки 4 часа БД будет недоступна, пытаясь откатить все эти изменения. То же будет в случае отката по ошибки в процессе обработки (я думаю, что именно по этой причине там сделали создание журнала с ошибками вместо отката всех строк, как в заказах на покупку/продажу). Поэтому время на открытия/закрытия мелких транзакций выгоднее с точки зрения скорости. Но целостность данных дороже. |
|
Теги |
inventjournal, оптимизация, производительность, запрос (query) |
|
|