Переключение на Главную Страницу Страницы: 1 [2] 3 4  ОтправитьПечать
Очень популярная тема (более 25 ответов) Ускорить проведение документа (число прочтений - 15716 )
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Ускорить проведение документа
Ответ #15 - 15. Января 2011 :: 11:38
Печать  
Тогда агрегацию можно убрать.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #16 - 15. Января 2011 :: 14:59
Печать  
А левый джоин с регистром не даст разве дублирующих записей, если убрать агрегацию? Но на всякий случай проверю, как на работе появлюсь  Подмигивание
  
Наверх
 
IP записан
 
Злой Бобр
Junior Member
**
Отсутствует



Сообщений: 56
Местоположение: Украина, Кривой Рог
Зарегистрирован: 07. Марта 2009
Пол: Мужской
Re: Ускорить проведение документа
Ответ #17 - 17. Января 2011 :: 16:26
Печать  
Собственно в ПУБ действительно дурновато написан модуль проведения. Руки б за такое повыдергивать горе писателям. Но что есть то есть.
Если по уму то я переписываю (иногда полностью) модуль проведения для того что б можно было налету перепроводить базу. Делаю так:
Код
Выбрать все
Процедура ОбработкаПроведения()
    Если Константа.НашеПроведение=0 Тогда
	  // стандартное проведение
    Иначе
	  // наше перепроведение
    КонецЕсли;
КонецПроцедуры 


В своем проведении практически все на прямых запросах, в т.ч. есть куски записи напрямую в таблицы базы. Все выверено и протестировано, поэтому неговорите что это не есть гут - сам знаю, но мне нужна скорость поэтому так и делаю.
На время перепроведения создаю таблицы с остатками по узким местам расчетов, т.е. например есть узкое место со списанием партий - остатки по партиям рассчитал всего один раз и записал в таблицу, дальше уже из нее беру данные (ускорение получается весьма значительное). Естественно перепровожу только тот период где уже нельзя создать документов, что б неушло все насмарку.
Самое важное следить за курсорами, особенно бывает кто-то другой что-то как напишет и оставит курсор, потом меня дергают.
В общем дело это интересное, но необходимо терпение и наличие определенного опыта. В итоге можно добиться весьма значительных результатов. Так что главное не падать духом.  Улыбка
  

Если у вас есть деньги тогда мы идем к вам!!!
Наверх
ICQ  
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Ускорить проведение документа
Ответ #18 - 18. Января 2011 :: 01:57
Печать  
Злой Бобр писал(а) 17. Января 2011 :: 16:26:
Собственно в ПУБ действительно дурновато написан модуль проведения.
А можно конкретнее? А то уже не первый год работаю с ПУБ и особых проблем с типовым вариантом не замечал...

Злой Бобр писал(а) 17. Января 2011 :: 16:26:
Делаю так:
Код
Выбрать все
Процедура ОбработкаПроведения()
    Если Константа.НашеПроведение=0 Тогда
	  // стандартное проведение
    Иначе
	  // наше перепроведение
    КонецЕсли;
КонецПроцедуры 

А разве кто-то уже отменил параметр в процедуре ОбработкаПроведения и флаг-функцию ГрупповаяОбработка()?
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ускорить проведение документа
Ответ #19 - 21. Января 2011 :: 11:48
Печать  
Флаг-функция ГрупповаяОбработка() видит только перепроведение, вызванное через Операции -> Проведение документов...

А оно не всегда бывает удобным.
Плюс, программно перепроведение вызывается из тучи мест - и всюду дописывать передачу параметра, чтоб вызывать перепроведение в нужном режиме?


А вот обращение напрямую к константе - вопрос спорный и зависит от поставленной задачи.
Не стоит забывать, что обращение к константе всегда вызывает запрос в таблицу _1SConst, которая частенько бывает раздута за счет периодических значений.
Т.е. иногда имеет смысл создать глобальную переменную и при начале работы записывать туда значение константы.

Dmitry The Wing писал(а) 18. Января 2011 :: 01:57:
Злой Бобр писал(а) 17. Января 2011 :: 16:26:
Собственно в ПУБ действительно дурновато написан модуль проведения.
А можно конкретнее? А то уже не первый год работаю с ПУБ и особых проблем с типовым вариантом не замечал...

Да там каждый второй модуль проведения такой, что хоть вешайся.
Отчасти, это обусловлено тем, что первичный учет построен на регистрах; а по сформированным движениям пишутся проводки. Но только отчасти.
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ускорить проведение документа
Ответ #20 - 21. Января 2011 :: 11:56
Печать  
Злой Бобр писал(а) 17. Января 2011 :: 16:26:
В своем проведении практически все на прямых запросах, в т.ч. есть куски записи напрямую в таблицы базы. Все выверено и протестировано, поэтому неговорите что это не есть гут - сам знаю, но мне нужна скорость поэтому так и делаю.


Прямой Insert/Update таблиц 1Ски требуется крайне редко.
Обычно достаточно сбора данных прямым запросом.
Стандартный метод ДвижениеПриходВыполнить() делает махинации со скулем вполне нормально.
Много скорости на этом не выиграть.
Разве что, у тебя документы по 100+ тысяч строк, и движения ты пишешь одним офигенным прямым запросом.
  
Наверх
 
IP записан
 
Злой Бобр
Junior Member
**
Отсутствует



Сообщений: 56
Местоположение: Украина, Кривой Рог
Зарегистрирован: 07. Марта 2009
Пол: Мужской
Re: Ускорить проведение документа
Ответ #21 - 21. Января 2011 :: 13:47
Печать  
Согласен. Запись в таблицы документов идет. Специально немерял, но есть такое предположение что напрямую отрабатывать должно быстрей чем 1С методами. Хотя может и неправ, спорить небуду.
  

Если у вас есть деньги тогда мы идем к вам!!!
Наверх
ICQ  
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Ускорить проведение документа
Ответ #22 - 24. Января 2011 :: 01:53
Печать  
Satans Claws писал(а) 21. Января 2011 :: 11:48:
Флаг-функция ГрупповаяОбработка() видит только перепроведение, вызванное через Операции -> Проведение документов...

А оно не всегда бывает удобным.
Плюс, программно перепроведение вызывается из тучи мест - и всюду дописывать передачу параметра, чтоб вызывать перепроведение в нужном режиме?
Ключевое слово "программно", т.е. описано руками прогера, а значит, - процесс написания кода им контроллировался, включая передачу параметра... А если он сразу не подумал, то это не является причиной не использовать сей метод...

Satans Claws писал(а) 21. Января 2011 :: 11:48:
Dmitry The Wing писал(а) 18. Января 2011 :: 01:57:
Злой Бобр писал(а) 17. Января 2011 :: 16:26:
Собственно в ПУБ действительно дурновато написан модуль проведения.
А можно конкретнее? А то уже не первый год работаю с ПУБ и особых проблем с типовым вариантом не замечал...

Да там каждый второй модуль проведения такой, что хоть вешайся.
Отчасти, это обусловлено тем, что первичный учет построен на регистрах; а по сформированным движениям пишутся проводки. Но только отчасти.

Все обработки проведения в ПУБ, что приходилось дорабатывать (а это все используемые документы, т.к. практически во всех регистрах изменен набор измерений), делают и делали до меня пересчет регистров только раз, как и все записи... разве что проводки, но они обычно делаются вызовом одной глобальной процедуры в конце проведения.
Потому и прошу пример, т.к. для меня ваши утверждения являются большим сюрпризом ... может дело в предыдущих наработках других прогеров? Такие перлы изменять приходилось, но не в типовой, а в той ПУБ, которая уже более 5 лет перестала быть типовой...
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ускорить проведение документа
Ответ #23 - 24. Января 2011 :: 05:46
Печать  
Да начиная с незабываемого
Код
Выбрать все
ЧтоСписывать = "000000100"; 

Улыбка

Ну и на примере документа Поступление из переработки:
например, такая строка:
Код
Выбрать все
СпособСписания = глСпособСписания(ВидМПЗ.Идентификатор(), ДатаДок);
Если (СпособСписания = 9) Тогда
	СтатусВозврата(0);
КонецЕсли; 



Это делается в цикле по строкам.
При этом, чуть выше (в этом же цикле) стоит куча проверок (заполненность реквизитов ТЧ документа) - и эта куча проверок завершается вполне логичным
Код
Выбрать все
Если ЕстьОшибкиЗаполнения = 1 Тогда
	Продолжить;
КонецЕсли; 

- чтоб просто показать ошибки по строкам, не гоняя тяжелые алгоритмы. (Хотя, на вскидку, мне помнится даже вариант с проверкой СтатусВозврата() = 0, вместо ЕстьОшибкиЗаполнения)

Хотя их вариант "ЕстьОшибкиЗаполнения" УЖЕ спорное решение. Мое мнение: уж лучше сделать лишний (отдельный) проход по строкам документа, в котором проверять заполненность (ну, может подготавливать какие дополнительные данные - какую-то ТЗ набить...).
Ибо такая простая вещь, как "автовод новой строки" в руках неопытного пользователя оборачивается документами с пустой последней строкой - и в стандартном ПУБе это означает, что мы по полной прогнали проведение, чтоб потом сказать "Ахтунг! строка незаполнена!!!!!".
И то, что по дефолту автоввод новой строки в ПУБе, может быть, и не включен - не отменяет порочности подхода.
  
Наверх
 
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Ускорить проведение документа
Ответ #24 - 24. Января 2011 :: 06:19
Печать  
Satans Claws писал(а) 24. Января 2011 :: 05:46:
Да начиная с незабываемого
Код
Выбрать все
ЧтоСписывать = "000000100"; 

Улыбка

Это то как раз ускоряет расчет регистров... Точнее то, как это потом используется.

Satans Claws писал(а) 24. Января 2011 :: 05:46:
Ну и на примере документа Поступление из переработки:

Посмотрел. Документ, действительно, интересный ... но у меня не используется ... видимо, потому и не напоролся ...

А проверка строк везде делается в момент проведения. Лучше варианта как бы и придумать сложно, потому как при успешном проведении это экономит уйму времени, а считать исключения правилом - глупо, ибо это означает ошибку в организации производства, а не в локике проги...

От себя добавлял подобные проверки в обработке записи, когда точно известно, что строки не могут быть неправильными, и ошибка объясняется только невнимательностью оператора... Но проверку остатков туда никак не засунешь...
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ускорить проведение документа
Ответ #25 - 24. Января 2011 :: 06:45
Печать  
Dmitry The Wing писал(а) 24. Января 2011 :: 06:19:
Satans Claws писал(а) 24. Января 2011 :: 05:46:
Да начиная с незабываемого
Код
Выбрать все
ЧтоСписывать = "000000100"; 

Улыбка

Это то как раз ускоряет расчет регистров... Точнее то, как это потом используется.

Ну, здесь косяк не в быстродействии, а в качестве кода.
Ибо каждый раз, когда я это вижу я, а) начинаю считать номера позиций; б) начинаю смотреть в глобале, а за что же отвечает каждая позиция.
Можно придумать несколько других схем передачи этого хитрого параметра, чтоб его можно было точно так же собирать в документе и парсить в глобале (например, банально через СписокЗначений.Установить("<ИмяРегистра>", 1)).

Цитата:
А проверка строк везде делается в момент проведения. Лучше варианта как бы и придумать сложно, потому как при успешном проведении это экономит уйму времени, а считать исключения правилом - глупо, ибо это означает ошибку в организации производства, а не в локике проги...

От себя добавлял подобные проверки в обработке записи, когда точно известно, что строки не могут быть неправильными, и ошибка объясняется только невнимательностью оператора... Но проверку остатков туда никак не засунешь...

Ну, по хорошему, да - проверка заполнения реквизитов делается при записи.
А при проведении делается проверка остатков + подготовка таблицы партий для ФИФО (ЛИФО).
Но в ПУБе это все нах#рачено в модуль проведения.

А, вот еще вспомнил - далеко не всегда проводки создаются в единственном месте (как завершение ОбработкиПроведения()).
Например, глРасчетыПриПоступлении() сама формирует проводки
  
Наверх
 
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Ускорить проведение документа
Ответ #26 - 24. Января 2011 :: 07:58
Печать  
Satans Claws писал(а) 24. Января 2011 :: 06:45:
А, вот еще вспомнил - далеко не всегда проводки создаются в единственном месте (как завершение ОбработкиПроведения()).
Например, глРасчетыПриПоступлении() сама формирует проводки

Которая сама выполняется в завершении обработки проведения Подмигивание
  
Наверх
 
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #27 - 08. Февраля 2011 :: 10:29
Печать  
Написал получение остатков в модуле проведения расходной накладной прямым запросом. Если проведение идет задним числом, получается в разы быстрее. Но если проведение идет текущим временем (на ТА), то прямой запрос стабильно медленнее. Замеряю с помощью функции _GetPerformanceCounter(), при штатном расчете остатков (ОстаткиПолучить()) документ на 8 строк проводится где-то за 140-150 мс, при прямом запросе - за 160-180мс.

Вот текст прямого запроса. Там мне надо получить остатки, стоимость и резервы на складе, плюс общий остаток, путь и резервы по каждой позиции. Как еще можно оптимизировать?

-------------------------------------------------------------------------------

ИТЗ=СоздатьОбъект("ИндексированнаяТаблица");
     
     Recordset.УстановитьТекстовыйПараметр("ТекДок",ТекущийДокумент());
     щийДокумент(),0));
     Recordset.УстановитьТекстовыйПараметр("перУслуга",перУслуга);
Recordset.УстановитьТекстовыйПараметр("Склад",Склад);
     
     Если ИтогиАктуальны()=1 Тогда
           ДатаРасч="";
     Иначе
           ДатаРасч=":ТекПоз~";
     КонецЕсли;
     
     Соед="
     |INNER JOIN $ДокументСтроки.РасходнаяНакладная as Д ON Д.IDDOC=:ТекДок AND Товар=$Д.Товар
     |";
     
     ДопСоединения="";
     ДопПоля="";
     
     Если ДокументОснование.Вид()="Счет" Тогда
           Recordset.УстановитьТекстовыйПараметр("ДокОсн",ДокументОснование);
           Recordset.УстановитьТекстовыйПараметр("ДокОснСклад",ДокументОснование.Склад);
           ДопСоединения=ДопСоединения+"
           |LEFT JOIN
           |$РегистрОстатки.РезервыТоваров("+ДатаРасч+","+Соед+",Товар=$Д.Товар AND Склад=:ДокОснСклад AND Счет=:ДокОсн~,(Товар),(Количество)) as РегРез ON $Док.Товар=РегРез.Товар";
           ДопПоля=ДопПоля+",
           |РегРез.КоличествоОстаток AS РезКол";
     КонецЕсли;
     
     //Общие остатки
     ДопСоединения=ДопСоединения+"
     |LEFT JOIN
     личество)) as Рег1 ON $Док.Товар=Рег1.Товар";
     ДопПоля=ДопПоля+",
     |Рег1.КоличествоОстаток AS ОбщКол";

     //Общий путь
     ДопСоединения=ДопСоединения+"
     |LEFT JOIN
     оличество)) as РегП ON $Док.Товар=РегП.Товар";
     ДопПоля=ДопПоля+",
     |РегП.КоличествоОстаток AS ОбщПуть";

     //Общие резервы
     ДопСоединения=ДопСоединения+"
     |LEFT JOIN
     личество)) as РегРез1 ON $Док.Товар=РегРез1.Товар";
     ДопПоля=ДопПоля+",
     |РегРез1.КоличествоОстаток AS ОбщРезКол";
     
***

     ТекстЗапроса="
     |SELECT
     |$Док.Товар as [Товар $Справочник.Товары],
     |$Док.Количество as [Кол],
     |Рег.КоличествоОстаток as [Ост],
     |РегПарт.КоличествоОстаток AS СебестКол,
     |РегПарт.СуммаУпрОстаток AS СебестУпр,
     |РегПарт.СуммаРубОстаток AS СебестРуб"
     +ДопПоля+"
     |FROM
     |$ДокументСтроки.РасходнаяНакладная as Док
     |LEFT JOIN
     |$Справочник.Товары as СпрТов ON $Док.Товар=СпрТов.ID
     |LEFT JOIN
     |$РегистрОстатки.ОстаткиТоваров("+ДатаРасч+","+Соед+",Товар=$Д.Товар AND Склад=:Склад,(Товар),(Количество)) as Рег ON $Док.Товар=Рег.Товар
     |LEFT JOIN
     ичество,СуммаУпр,СуммаРуб)) as РегПарт ON $Док.Товар=РегПарт.Товар"
     +ДопСоединения+"
     |WHERE
     |Док.IDDOC=:ТекДок AND $СпрТов.ВидТовара<>:перУслуга
     |";
     
     RecordSet.ВыполнитьИнструкцию(ТекстЗапроса, ИТЗ);
     
     Если КонстРазрОтрицОст=Перечисление.Булево.Нет Тогда
           ИТЗ.ВыбратьСтроки();
           Пока ИТЗ.ПолучитьСтроку()=1 Цикл
                 Если ИТЗ.Кол>ИТЗ.Ост Тогда
                       Сообщить("На складе нет товара "+ИТЗ.Товар+". Не смог провести!");
                       СтатусВозврата(0);
                       Возврат;
                 КонецЕсли;
           КонецЦикла;
     КонецЕсли;
     
     ИТЗ.ДобавитьИндекс("ИндТовар","Товар",0);

     ВыбратьСтроки();
     Пока ПолучитьСтроку()=1 Цикл
           Если ИТЗ.НайтиСтроку("ИндТовар",Товар,0,1)>0 Тогда
                 
           КонецЕсли;
     КонецЦикла;
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Ускорить проведение документа
Ответ #28 - 08. Февраля 2011 :: 10:57
Печать  
Как-то получать остатки для каждой строки вообще не комильфо.
Проще 1 запрос к остаткам по списку номенклатуры из табличной части и привет.
И без кучи соединений.
  
Наверх
 
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #29 - 08. Февраля 2011 :: 11:21
Печать  
Имеешь в виду, что лучше не получать табличную часть запросом и потом джойнить регистры, а сразу запрос к регистру по списку товаров табличной части? Так будет быстрее?
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1 [2] 3 4 
ОтправитьПечать