1С 8.3. Как оптимизировать данный код? Долго грузится
Есть такой код:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| РегистрНакопленияПартииТоваров.Номенклатура Как Номенклатура,
| СУММА(РегистрНакопленияПартииТоваров.Количество) Как Количество,
| МАКСИМУМ(ЕСТЬNULL(УчетНоменклатурыОстатки.КоличествоОстаток, 0)) КАК КоличествоОстаток,
| МАКСИМУМ(ЕСТЬNULL(РегистрНакопленияПартииТоваров.СуммаУпр, 0)) КАК СебестоимостьУпр,
| МАКСИМУМ(ЕСТЬNULL(ПартииТоваровКомпанииОстаткиИОбороты.КоличествоРасход, 0)) КАК КоличествоРасход,
| МАКСИМУМ(ЕСТЬNULL(ПартииТоваровКомпанииОстаткиИОборотыНеделя.КоличествоРасход, 0)) КАК КоличествоРасходНеделя
|ИЗ
| РегистрНакопления.ПартииТоваровКомпании КАК РегистрНакопленияПартииТоваров
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваровКомпании.Остатки КАК УчетНоменклатурыОстатки
| ПО УчетНоменклатурыОстатки.Номенклатура.Артикул = РегистрНакопленияПартииТоваров.Номенклатура.Артикул
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровКомпании.ОстаткиИОбороты(&НачПериода,&КонецПериода) КАК ПартииТоваровКомпанииОстаткиИОбороты
| ПО ПартииТоваровКомпанииОстаткиИОбороты.Номенклатура.Артикул = РегистрНакопленияПартииТоваров.Номенклатура.Артикул
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровКомпании.ОстаткиИОбороты(&НачПериодаНеделя,&КонецПериодаНеделя) КАК ПартииТоваровКомпанииОстаткиИОборотыНеделя
| ПО ПартииТоваровКомпанииОстаткиИОборотыНеделя.Номенклатура.Артикул = РегистрНакопленияПартииТоваров.Номенклатура.Артикул
|ГДЕ РегистрНакопленияПартииТоваров.Период МЕЖДУ НАЧАЛОПЕРИОДА(&НачалоДаты) И КОНЕЦПЕРИОДА(&КонецДаты) И
|РегистрНакопленияПартииТоваров.ХозОперация = &ХозОперация
|СГРУППИРОВАТЬ ПО РегистрНакопленияПартииТоваров.Номенклатура";
Запрос.УстановитьПараметр("НачалоДаты",ДатаНачала);
Запрос.УстановитьПараметр("КонецДаты",ДатаОкончания);
Запрос.УстановитьПараметр("НачПериода", ДобавитьМесяц(ТекущаяДата(), -12) );
Запрос.УстановитьПараметр("КонецПериода",ТекущаяДата());
Запрос.УстановитьПараметр("ХозОперация",Справочники.ХозОперации.НайтиПоНаименованию("Перемещение товаров в производство"));
Запрос.УстановитьПараметр("НачПериодаНеделя", ТекущаяДата()-60*60*24*7 );
Запрос.УстановитьПараметр("КонецПериодаНеделя",ТекущаяДата());
ТаблицаОтчета = Запрос.Выполнить().Выбрать();
Код начал долго грузиться после добавления еще одного левого соединения:
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровКомпании.ОстаткиИОбороты(&НачПериодаНеделя,&КонецПериодаНеделя) КАК ПартииТоваровКомпанииОстаткиИОборотыНеделя
ПО ПартииТоваровКомпанииОстаткиИОборотыНеделя.Номенклатура.Артикул = РегистрНакопленияПартииТоваров.Номенклатура.Артикул
Как оптимизировать данный код?
Точнее вот эти две левые соединении (можно ли их как-то объединить, но чтобы параметры периодов были разными):
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровКомпании.ОстаткиИОбороты(&НачПериода,&КонецПериода) КАК ПартииТоваровКомпанииОстаткиИОбороты
ПО ПартииТоваровКомпанииОстаткиИОбороты.Номенклатура.Артикул = РегистрНакопленияПартииТоваров.Номенклатура.Артикул
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровКомпании.ОстаткиИОбороты(&НачПериодаНеделя,&КонецПериодаНеделя) КАК ПартииТоваровКомпанииОстаткиИОборотыНеделя
ПО ПартииТоваровКомпанииОстаткиИОборотыНеделя.Номенклатура.Артикул = РегистрНакопленияПартииТоваров.Номенклатура.Артикул
Ответы (1 шт):
1 - Остатки нужно получать на определенную дату
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваровКомпании.Остатки(&НаДату) КАК УчетНоменклатурыОстатки
2 - Условие соединения следует проверить, - точно .Номенклатура.Артикул ?! Если Артикулы номенклатуры не ведутся, достаточно соединить по Номенклатура
ПО УчетНоменклатурыОстатки.Номенклатура = РегистрНакопленияПартииТоваров.Номенклатура
Если Артикулы ведутся тогда, для подстраховки я бы использовал (чтобы исключить ситуацию когда у разной номенклатуры одинаковый артикул)
ПО УчетНоменклатурыОстатки.Номенклатура = РегистрНакопленияПартииТоваров.Номенклатура
И УчетНоменклатурыОстатки.Номенклатура.Артикул = РегистрНакопленияПартииТоваров.Номенклатура.Артикул
3 - Условие соединения следует использовать во всех соединениях.
4 - МАКСИМУМ() нужно убрать* (при использовании оптимизации, в исходном запросе имеет определенный смысл)
5 - Если стоит задача оптимизации запроса в целом, - желательно использовать временные таблицы; Это не простая задача, но в общих чертах можно сказать следующее:
ВЫБРАТЬ
РегистрНакопленияПартииТоваров.Номенклатура Как Номенклатура,
СУММА(РегистрНакопленияПартииТоваров.Количество) Как Количество
ПОМЕСТИТЬ ВТ
СГРУППИРОВАТЬ ПО РегистрНакопленияПартииТоваров.Номенклатура
;
ВЫБРАТЬ Номенклатура
ПОМЕСТИТЬ ВТ_Номенклатура
ИЗ ВТ
ИНДЕКСИРОВАТЬ ПО Номенклатура
; // Сформируем список Номенклатуры
ВЫБРАТЬ
ВТ.Номенклатура,
ВТ.Количество,
ЕСТЬNULL(УчетНоменклатурыОстатки_.КоличествоОстаток, 0) КАК КоличествоОстаток
ИЗ ВТ
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ УчетНоменклатурыОстатки.КоличествоОстаток КАК КоличествоОстаток,
УчетНоменклатурыОстатки.Номенклатура КАК Номенклатура
ИЗ РегистрНакопления.ОстаткиТоваровКомпании.Остатки(&НаДату) КАК УчетНоменклатурыОстатки
ГДЕ УчетНоменклатурыОстатки.Номенклатура В (ВТ_Номенклатура)) КАК УчетНоменклатурыОстатки_
ПО УчетНоменклатурыОстатки_.Номенклатура = ВТ.Номенклатура
// Остальные ЛЕВОЕ СОЕДИНЕНИЕ следует описать аналогичным образом;