Имя: Пароль:
1C
 
Помогите разобраться с задачей по оптимизации запроса
0 Novichok VX
 
14.10.21
09:40
Есть такая задача "нужно оптимизировать запросы к регистру доп. Свойств. Сделать выражение конкретного типа в условии запроса.".
Есть например такой запрос, что там можно оптимизировать?
    запрос=новый запрос;
    запрос.Текст="ВЫБРАТЬ
                 |    РезкаНоменклатурыНаСклад.Номенклатура,
                 |    РезкаНоменклатурыНаСклад.Номенклатура.ВысотаММ КАК Высота,
                 |    РезкаНоменклатурыНаСклад.Номенклатура.ШиринаММ КАК Ширина,
                 |    РезкаНоменклатурыНаСклад.Номенклатура.ДлинаММ КАК длина,
                 |    ЕСТЬNULL(ЖесткостьМарки.Значение, 0) КАК Жесткость,
                 |    ЕСТЬNULL(ПлотностьМарки.Значение, 0) КАК Плотность,
                 |    РезкаНоменклатурыНаСклад.Исполнение
                 |ИЗ
                 |    РегистрСведений.РезкаНоменклатурыНаСклад КАК РезкаНоменклатурыНаСклад
                 |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДопсвойстваОбъектов КАК ПлотностьМарки
                 |        ПО РезкаНоменклатурыНаСклад.Марка = ПлотностьМарки.Объект
                 |            И (ПлотностьМарки.ВидДопсвойства = &СвПлотностьМарки)
                 |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДопсвойстваОбъектов КАК ЖесткостьМарки
                 |        ПО РезкаНоменклатурыНаСклад.Марка = ЖесткостьМарки.Объект
                 |            И (ЖесткостьМарки.ВидДопсвойства = &СвЖесткостьМарки)
                 |ГДЕ
                 |    РезкаНоменклатурыНаСклад.Использовать";
    запрос.УстановитьПараметр("СвПлотностьМарки",ПланыВидовХарактеристик.ВидыДопсвойств.НайтиПоКоду("00038"));            
    запрос.УстановитьПараметр("СвЖесткостьМарки",ПланыВидовХарактеристик.ВидыДопсвойств.НайтиПоКоду("00010"));            
    ТЗВрем=запрос.Выполнить().Выгрузить();
1 Novichok VX
 
14.10.21
09:42
еще такое есть
Функция ЗапросПоДопСвойствам(ОбъектЗапроса, КодДопСвойства)
    тРез = глВыполнитьЗапрос("
    |ВЫБРАТЬ
    |   Значение
    |ИЗ
    |   РегистрСведений.ДопсвойстваОбъектов
    |ГДЕ
    |   Объект = &ТекОбъект и
    |   ВидДопсвойства.Код = &ТекКод",
    Новый Структура("ТекОбъект,ТекКод",
    ОбъектЗапроса, КодДопСвойства));
    
    Если тРез.Количество()>0 тогда
        Возврат тРез[0].Значение;
    Иначе
        Возврат Неопределено;
    КонецЕсли;
КонецФункции
2 Novichok VX
 
14.10.21
09:44
может там первые 1 добавить, чтобы меньше выгружаемая таблица была?
3 Novichok VX
 
14.10.21
10:05
Еще такое есть. Может там надо использовать что то вроде значенияреквизитовобъекта, чтобы вся ссылка не вываливалась при обращении?

    тзПлотность=глВыполнитьЗапрос("ВЫБРАТЬ
                                  |    ВложенныйЗапрос.Ссылка,
                                  |    ДопсвойстваОбъектов.Значение КАК Плотность
                                  |ИЗ
                                  |    (ВЫБРАТЬ
                                  |        ДопсвойстваОбъектов.Значение КАК Значение,
                                  |        Номенклатура.Ссылка КАК Ссылка
                                  |    ИЗ
                                  |        Справочник.Номенклатура КАК Номенклатура
                                  |            ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДопсвойстваОбъектов КАК ДопсвойстваОбъектов
                                  |            ПО Номенклатура.Ссылка = ДопсвойстваОбъектов.Объект
                                  |    ГДЕ
                                  |        ДопсвойстваОбъектов.ВидДопсвойства = &ВидДопсвойства_МаркаПены) КАК ВложенныйЗапрос
                                  |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДопсвойстваОбъектов КАК ДопсвойстваОбъектов
                                  |        ПО ВложенныйЗапрос.Значение = ДопсвойстваОбъектов.Объект
                                  |ГДЕ
                                  |    ДопсвойстваОбъектов.ВидДопсвойства = &ВидДопсвойства_Плотность
                                  |    И ВложенныйЗапрос.Ссылка = &Ссылка",
                                  Новый Структура("ВидДопсвойства_МаркаПены,ВидДопсвойства_Плотность,Ссылка",
                                  ПланыВидовХарактеристик.ВидыДопсвойств.НайтиПоКоду("00009"),ПланыВидовХарактеристик.ВидыДопсвойств.НайтиПоКоду("00038"),Номенклатура));
    Если тзПлотность.Количество()=0 Тогда
        глСообщитьВажн("Для номенклатуры не определена плотность");
        Возврат 0;
    Иначе
        тПлотность=тзПлотность[0].Плотность;
    КонецЕсли;
4 Novichok VX
 
14.10.21
10:08
А, я понял, в запросе (0) можно отбор сделать в запросе по свойствам, а не выносить свойства в отбор ниже, чтобы память получаемой таблицей не забивать
5 Dmitrii
 
гуру
14.10.21
10:19
(1) Тут особо оптимизировать нечего. Даже если в глВыполнитьЗапрос какие-нибудь извращения происходят, вряд ли они сильно много накладных расходов несут.
(0) Тут можно попробовать сначала получить во временную таблицу данные по Номенклатуре и Марке из регистра РезкаНоменклатурыНаСклад с длиной высотой и шириной и с отбором по условию Использовать. Может даже приндексировать эту ВТ по полю Марка. А уже потом эту временную таблицу вязать с таблицами регистра Допсвойств. Имеет смысл, если регистр РезкаНоменклатурыНаСклад большой, а записей с флагом Использовать в нём немного.
И если уж делаете поиск по коду, то зачем именно объектными методами, а не прямо в запросе писать ПлотностьМарки.ВидДопсвойства.Код = &КодПлотностиМарки. Или ПлотностьМарки.ВидДопсвойства.Код = "00038"? Зачем эти извращения с поисками по коду и последующими установками значений параметров?

(4) >> можно отбор сделать в запросе по свойствам, а не выносить свойства в отбор ниже, чтобы память получаемой таблицей не забивать.

Может иметь смысл, если у вас свойств огромное количество.

И ради чего всё это делается?
Особой оптимизации вы тут вряд ли добьётесь. Если нужен реальный прирост, то лучше добавить в Марку необходимые реквизиты (Плотность, Жесткость и т.п.), а не хранить их в регистре ДопСвойств.
6 Dmitrii
 
гуру
14.10.21
10:24
Ну ещё проверьте, что код из (1) и из (3) не дёргается в цикле перебором по каждой номенклатуре. Если такое есть, переписать такие места на получение данных одним запросом по массиву или по таблице номенклатур.
Хотя всё равно производительность будет деградировать по мере роста количества Номенклатуры, Марок и регистра с допсвойствами.
7 acht
 
14.10.21
10:26
(0) > запрос.УстановитьПараметр("СвЖесткостьМарки",ПланыВидовХарактеристик.ВидыДопсвойств.НайтиПоКоду("00010"));

"Поиск по коду" можно перенести в текст запроса.
8 Dmitrii
 
гуру
14.10.21
10:39
(3) Фу.... Не заметил, что там ещё и вложенный запрос. Бред какой-то. Перепишите на обычный. Нафига получать во вложенном запросе допсвойства для всего справочника Номенклатура, чтобы потом внутренним соединением вытащить только одну единственную запись по одной номенклатуре? Что курил автор этого запроса?
9 Novichok VX
 
14.10.21
11:05
Подскажите, правильно ли в этом месте переделал. Вот что было до
запрос=новый запрос;
    запрос.Текст="ВЫБРАТЬ
                 |    СУММА(ПроизводственныеЗаданияОстатки.КоличествоЗаданиеОстаток) КАК ПланКоличество,
                 |    ПроизводственныеЗаданияОстатки.Номенклатура,
                 |    ПроизводственныеЗаданияОстатки.Заказ,
                 |    0 КАК ФактКоличество,
                 |    ПроизводственныеЗаданияОстатки.ИсполнениеНоменклатуры
                 |ПОМЕСТИТЬ ТЗ_График
                 |ИЗ
                 |    РегистрНакопления.ПроизводственныеЗадания.Остатки(
                 |            &ДатаОст,
                // |            ДатаЗапуска < НАЧАЛОПЕРИОДА(&ДатаОст, ДЕНЬ) и
                 |                Номенклатура В ИЕРАРХИИ (&Номенклатура)) КАК ПроизводственныеЗаданияОстатки
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    ПроизводственныеЗаданияОстатки.Номенклатура,
                 |    ПроизводственныеЗаданияОстатки.Заказ,
                 |    ПроизводственныеЗаданияОстатки.ИсполнениеНоменклатуры
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |ВЫБРАТЬ
                 |    СУММА(ТЗ_График.ПланКоличество) КАК ПланКоличество,
                 |    ТЗ_График.Номенклатура,
                 |    ТЗ_График.Заказ,
                 |    0 КАК ФактКоличество,
                 |    ТЗ_График.ИсполнениеНоменклатуры
                 |ПОМЕСТИТЬ ТЗ
                 |ИЗ
                 |    ТЗ_График КАК ТЗ_График
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    ТЗ_График.Номенклатура,
                 |    ТЗ_График.Заказ,
                 |    ТЗ_График.ИсполнениеНоменклатуры
                 |
                 //|ОБЪЕДИНИТЬ ВСЕ
                 //|
                 //|ВЫБРАТЬ
                 //|    СУММА(ПроизводственноеЗаданиетчПроизводственныеЗадания.КоличествоХранения),
                 //|    ПроизводственноеЗаданиетчПроизводственныеЗадания.Номенклатура,
                 //|    ПроизводственноеЗаданиетчПроизводственныеЗадания.Заказ,
                 //|    0,
                 //|    ПроизводственноеЗаданиетчПроизводственныеЗадания.ИсполнениеНоменклатуры
                 //|ИЗ
                 //|    Документ.ПроизводственноеЗадание.тчПроизводственныеЗадания КАК ПроизводственноеЗаданиетчПроизводственныеЗадания
                 //|ГДЕ
                 //|    ПроизводственноеЗаданиетчПроизводственныеЗадания.Ссылка.Проведен
                 //|    И ПроизводственноеЗаданиетчПроизводственныеЗадания.Ссылка.ДатаЗадания = НАЧАЛОПЕРИОДА(&ДатаОст, ДЕНЬ)
                 //|
                 //|СГРУППИРОВАТЬ ПО
                 //|    ПроизводственноеЗаданиетчПроизводственныеЗадания.Номенклатура,
                 //|    ПроизводственноеЗаданиетчПроизводственныеЗадания.Заказ,
                 //|    ПроизводственноеЗаданиетчПроизводственныеЗадания.ИсполнениеНоменклатуры
                 |
                 |ОБЪЕДИНИТЬ ВСЕ
                 |
                 |ВЫБРАТЬ
                 |    0,
                 |    СерииТМЦ.Владелец,
                 |    СерииТМЦ.Заказ,
                 |    СерииТМЦ.КоличествоХранения,
                 |    СерииТМЦ.ИсполнениеНоменклатуры
                 |ИЗ
                 |    Справочник.СерииТМЦ КАК СерииТМЦ
                 |ГДЕ
                 |    СерииТМЦ.ДатаИзготовления >= началопериода(&ДатаОст,день)
                 |    И СерииТМЦ.Владелец В ИЕРАРХИИ
                 |            (ВЫБРАТЬ
                 |                ТЗ_График.Номенклатура
                 |            ИЗ
                 |                ТЗ_График КАК ТЗ_График
                 |            СГРУППИРОВАТЬ ПО
                 |                        ТЗ_График.Номенклатура)
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |ВЫБРАТЬ
                 |    СУММА(ТЗ.ПланКоличество - ТЗ.ФактКоличество) КАК КолВоОст,
                 |    ТЗ.Номенклатура,
                 |    ТЗ.Заказ,
                 |    ЕСТЬNULL(ЖесткостьМарки.Значение, 0) КАК Жесткость,
                 |    ЕСТЬNULL(ПлотностьМарки.Значение, 0) КАК Плотность,
                 |    ТЗ.ИсполнениеНоменклатуры,
                 |    ТЗ.Номенклатура.ВысотаММ КАК Высота,
                 |    ТЗ.Номенклатура.ШиринаММ КАК Ширина,
                 |    ТЗ.Номенклатура.ДлинаММ КАК Длина,
                 |    ТЗ.Заказ.Номер
                 |ИЗ
                 |    ТЗ КАК ТЗ
                 |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДопсвойстваОбъектов КАК ПлотностьМарки
                 |        ПО ТЗ.Номенклатура.ФантомСебестоимости = ПлотностьМарки.Объект
                 |            И (ПлотностьМарки.ВидДопсвойства = &СвПлотностьМарки)
                 |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДопсвойстваОбъектов КАК ЖесткостьМарки
                 |        ПО ТЗ.Номенклатура.ФантомСебестоимости = ЖесткостьМарки.Объект
                 |            И (ЖесткостьМарки.ВидДопсвойства = &СвЖесткостьМарки)
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    ТЗ.Заказ,
                 |    ТЗ.Номенклатура,
                 |    ЕСТЬNULL(ЖесткостьМарки.Значение, 0),
                 |    ЕСТЬNULL(ПлотностьМарки.Значение, 0),
                 |    ТЗ.ИсполнениеНоменклатуры,
                 |    ТЗ.Номенклатура.ВысотаММ,
                 |    ТЗ.Номенклатура.ШиринаММ,
                 |    ТЗ.Номенклатура.ДлинаММ
                 |
                 |ИМЕЮЩИЕ
                 |    СУММА(ТЗ.ПланКоличество - ТЗ.ФактКоличество) > 0
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |УНИЧТОЖИТЬ ТЗ
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |УНИЧТОЖИТЬ ТЗ_График";
    CпСостояний=новый списокзначений;
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.ВПроизводстве);
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.Готовность);
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.Открыт);
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.ОтгруженЧастично);
    
    
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.Отгружен);
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.Отменен);
    
    //запрос.УстановитьПараметр("Номенклатура",НоменклатураВыпуска);
    запрос.УстановитьПараметр("ДатаОст",НачалоДня(ПлДатаПр)+3600*6);
    //запрос.УстановитьПараметр("ДатаОст",текущаядата());
    запрос.УстановитьПараметр("CпСостояний",CпСостояний);
    запрос.УстановитьПараметр("СвПлотностьМарки",ПланыВидовХарактеристик.ВидыДопсвойств.НайтиПоКоду("00038"));            
    запрос.УстановитьПараметр("СвЖесткостьМарки",ПланыВидовХарактеристик.ВидыДопсвойств.НайтиПоКоду("00010"));    
    спНоменклатуры=новый списокзначений;
    спНоменклатуры.добавить(справочники.Номенклатура.НайтиПоКоду("ФМ002195"));
    спНоменклатуры.добавить(справочники.Номенклатура.НайтиПоКоду("ФМ005267"));
    запрос.УстановитьПараметр("номенклатура",спНоменклатуры);            
    ТЗВрем=запрос.Выполнить().Выгрузить();


А вот после переделки

запрос=новый запрос;
    запрос.Текст="ВЫБРАТЬ
                 |    СУММА(ПроизводственныеЗаданияОстатки.КоличествоЗаданиеОстаток) КАК ПланКоличество,
                 |    ПроизводственныеЗаданияОстатки.Номенклатура,
                 |    ПроизводственныеЗаданияОстатки.Заказ,
                 |    0 КАК ФактКоличество,
                 |    ПроизводственныеЗаданияОстатки.ИсполнениеНоменклатуры
                 |ПОМЕСТИТЬ ТЗ_График
                 |ИЗ
                 |    РегистрНакопления.ПроизводственныеЗадания.Остатки(&ДатаОст, Номенклатура В ИЕРАРХИИ (&Номенклатура)) КАК ПроизводственныеЗаданияОстатки
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    ПроизводственныеЗаданияОстатки.Номенклатура,
                 |    ПроизводственныеЗаданияОстатки.Заказ,
                 |    ПроизводственныеЗаданияОстатки.ИсполнениеНоменклатуры
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |ВЫБРАТЬ
                 |    СУММА(ТЗ_График.ПланКоличество) КАК ПланКоличество,
                 |    ТЗ_График.Номенклатура,
                 |    ТЗ_График.Заказ,
                 |    0 КАК ФактКоличество,
                 |    ТЗ_График.ИсполнениеНоменклатуры
                 |ПОМЕСТИТЬ ТЗ
                 |ИЗ
                 |    ТЗ_График КАК ТЗ_График
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    ТЗ_График.Номенклатура,
                 |    ТЗ_График.Заказ,
                 |    ТЗ_График.ИсполнениеНоменклатуры
                 |
                 |ОБЪЕДИНИТЬ ВСЕ
                 |
                 |ВЫБРАТЬ
                 |    0,
                 |    СерииТМЦ.Владелец,
                 |    СерииТМЦ.Заказ,
                 |    СерииТМЦ.КоличествоХранения,
                 |    СерииТМЦ.ИсполнениеНоменклатуры
                 |ИЗ
                 |    Справочник.СерииТМЦ КАК СерииТМЦ
                 |ГДЕ
                 |    СерииТМЦ.ДатаИзготовления >= НАЧАЛОПЕРИОДА(&ДатаОст, ДЕНЬ)
                 |    И СерииТМЦ.Владелец В ИЕРАРХИИ
                 |            (ВЫБРАТЬ
                 |                ТЗ_График.Номенклатура
                 |            ИЗ
                 |                ТЗ_График КАК ТЗ_График
                 |            СГРУППИРОВАТЬ ПО
                 |                ТЗ_График.Номенклатура)
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |ВЫБРАТЬ
                 |    СУММА(ТЗ.ПланКоличество - ТЗ.ФактКоличество) КАК КолВоОст,
                 |    ТЗ.Номенклатура,
                 |    ТЗ.Заказ,
                 |    ЕСТЬNULL(ЖесткостьМарки.Значение, 0) КАК Жесткость,
                 |    ЕСТЬNULL(ПлотностьМарки.Значение, 0) КАК Плотность,
                 |    ТЗ.ИсполнениеНоменклатуры,
                 |    ТЗ.Номенклатура.ВысотаММ КАК Высота,
                 |    ТЗ.Номенклатура.ШиринаММ КАК Ширина,
                 |    ТЗ.Номенклатура.ДлинаММ КАК Длина,
                 |    ТЗ.Заказ.Номер
                 |ИЗ
                 |    ТЗ КАК ТЗ
                 |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДопсвойстваОбъектов КАК ПлотностьМарки
                 |        ПО ТЗ.Номенклатура.ФантомСебестоимости = ПлотностьМарки.Объект
                 |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДопсвойстваОбъектов КАК ЖесткостьМарки
                 |        ПО ТЗ.Номенклатура.ФантомСебестоимости = ЖесткостьМарки.Объект
                 |ГДЕ
                 |    ПлотностьМарки.ВидДопсвойства.Код = ""00038""
                 |    И ЖесткостьМарки.ВидДопсвойства.Код = ""00010""
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    ТЗ.Заказ,
                 |    ТЗ.Номенклатура,
                 |    ЕСТЬNULL(ЖесткостьМарки.Значение, 0),
                 |    ЕСТЬNULL(ПлотностьМарки.Значение, 0),
                 |    ТЗ.ИсполнениеНоменклатуры,
                 |    ТЗ.Номенклатура.ВысотаММ,
                 |    ТЗ.Номенклатура.ШиринаММ,
                 |    ТЗ.Номенклатура.ДлинаММ,
                 |    ТЗ.Заказ.Номер
                 |
                 |ИМЕЮЩИЕ
                 |    СУММА(ТЗ.ПланКоличество - ТЗ.ФактКоличество) > 0
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |УНИЧТОЖИТЬ ТЗ
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |УНИЧТОЖИТЬ ТЗ_График";
    CпСостояний=новый списокзначений;
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.ВПроизводстве);
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.Готовность);
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.Открыт);
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.ОтгруженЧастично);
    
    
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.Отгружен);
    CпСостояний.Добавить(перечисления.СостоянияЗаказа.Отменен);
    
    //запрос.УстановитьПараметр("Номенклатура",НоменклатураВыпуска);
    запрос.УстановитьПараметр("ДатаОст",НачалоДня(ПлДатаПр)+3600*6);
    //запрос.УстановитьПараметр("ДатаОст",текущаядата());
    запрос.УстановитьПараметр("CпСостояний",CпСостояний);
    //запрос.УстановитьПараметр("СвПлотностьМарки",ПланыВидовХарактеристик.ВидыДопсвойств.НайтиПоКоду("00038"));            
    //запрос.УстановитьПараметр("СвЖесткостьМарки",ПланыВидовХарактеристик.ВидыДопсвойств.НайтиПоКоду("00010"));    
    спНоменклатуры=новый списокзначений;
    спНоменклатуры.добавить(справочники.Номенклатура.НайтиПоКоду("ФМ002195"));
    спНоменклатуры.добавить(справочники.Номенклатура.НайтиПоКоду("ФМ005267"));
    запрос.УстановитьПараметр("номенклатура",спНоменклатуры);            
    ТЗВрем=запрос.Выполнить().Выгрузить();
10 DexterMorgan
 
14.10.21
11:13
РезкаНоменклатурыНаСклад.Марка = ПлотностьМарки.Объект

заменить на Выразить(РезкаНоменклатурыНаСклад.Марка КАК ТипЭтойШтуки) = бла бла бла
11 Novichok VX
 
14.10.21
11:17
(10)
спс, мне собственно начальник то же самое только что сказал
12 Dmitrii
 
гуру
14.10.21
13:52
(10) (11) Не будет иметь никакого смысла, если нет обращений к полям через точку от Марка.
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.