Написал получение остатков в модуле проведения расходной накладной прямым запросом. Если проведение идет задним числом, получается в разы быстрее. Но если проведение идет текущим временем (на ТА), то прямой запрос стабильно медленнее. Замеряю с помощью функции _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 Тогда КонецЕсли; КонецЦикла;
|