Имя: Пароль:
1C
 
Прошу совета по оптимизации кода в событии "ПриПолученииДанных"
0 evorle145
 
19.11.14
11:20
Хочется сделать в справочнике номенклатура Колонки "Цена" и "Остаток", учитывая что склад один, учет по характеристикам не ведется.

Собираю таблицу с ссылками и индексами, потом левым соединением вытаскиваю из регистров данные.. но проблема в том, что очень заметное подвисание. Замер производительности показывает, что узкое место в этом запросе:

Запрос.Текст ="ВЫБРАТЬ
                  |    ЦеныНоменклатурыСрезПоследних.Номенклатура,
                  |    МАКСИМУМ(ЦеныНоменклатурыСрезПоследних.Цена) КАК Цена
                  |ПОМЕСТИТЬ Цена
                  |ИЗ
                  |    РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
                  |ГДЕ
                  |    ЦеныНоменклатурыСрезПоследних.ТипЦен = &ТипЦен
                  |
                  |СГРУППИРОВАТЬ ПО
                  |    ЦеныНоменклатурыСрезПоследних.Номенклатура
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |    ТоварыНаСкладахОстатки.Номенклатура,
                  |    СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток) КАК КоличествоОстаток
                  |ПОМЕСТИТЬ Остаток
                  |ИЗ
                  |    РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
                  |
                  |СГРУППИРОВАТЬ ПО
                  |    ТоварыНаСкладахОстатки.Номенклатура
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ РАЗЛИЧНЫЕ
                  |    ВременнаяТаблица.СсылкаЗ КАК СсылкаЗ,
                  |    ВременнаяТаблица.Индекс КАК Индекс1,
                  |    диск.Цена,
                  |    Остаток.КоличествоОстаток
                  |ИЗ
                  |    ТаблицаИндексСсылка КАК ВременнаяТаблица
                  |        ЛЕВОЕ СОЕДИНЕНИЕ Цена КАК диск
                  |        ПО ВременнаяТаблица.СсылкаЗ = диск.Номенклатура
                  |        ЛЕВОЕ СОЕДИНЕНИЕ Остаток КАК Остаток
                  |        ПО ВременнаяТаблица.СсылкаЗ = Остаток.Номенклатура
                  |
                  |УПОРЯДОЧИТЬ ПО
                  |    Индекс1";


Посоветуйте, как его оптимизировать
1 pessok
 
19.11.14
11:22
(0) у тебя запрос в ПриПолученииДанных() чтоль?
2 pessok
 
19.11.14
11:22
+(1) сделай в ПриОткрытии() если не критично, клади во временную ТЗ, а в ПриПолученииДанных() уже работай со своей таблицей
3 Широкий
 
19.11.14
11:23
(0) Фильтр ставь. Ты считываешь все возможные остатки и цены. Очень не хорошо
4 evorle145
 
19.11.14
11:23
(1) , ага... Может его вынести например в "ПриОткрытии"? Но тогда есть вероятность что будут отображаться не совсем последние данные по ценам  и остаткам..
5 pessok
 
19.11.14
11:23
ну и да, индексируй по номенклатуре [0] и [1]
6 evorle145
 
19.11.14
11:24
(3) , а что за фильтр имеется ввиду?
7 pessok
 
19.11.14
11:25
(3) а как ему ставить фильтр на форме списка то?
8 pessok
 
19.11.14
11:25
(4) сделай еще обработку ожидания, раз в 30 секунд обновляй свою таблицу, например
9 pessok
 
19.11.14
11:26
+(8) чтобы избежать "а я с утра список открыл, там еще ничего не было зарезервировано!"
10 Йохохо
 
19.11.14
11:27
(7) приполученииданных как фильтр ставить?
11 John83
 
19.11.14
11:32
МассивСсылок = Новый Массив;
СоответствиеОформлений = Новый Соответствие;

Для Каждого ОфомрлениеСтроки Из ОформленияСтрок Цикл        
    СоответствиеОформлений.Вставить(ОфомрлениеСтроки.ДанныеСтроки.Номенклатура, ОфомрлениеСтроки);
    МассивСсылок.Добавить(ОфомрлениеСтроки.ДанныеСтроки.Номенклатура);        
КонецЦикла;

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    ТоварыНаСкладахОстатки.Номенклатура,
|    ТоварыНаСкладахОстатки.КоличествоОстаток
|ИЗ
|    РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура В (&СписокСсылок)) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("СписокСсылок", МассивСсылок);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    ОформлениеСтроки = СоответствиеОформлений.Получить(Выборка.Номенклатура);
    Если ОформлениеСтроки <> Неопределено Тогда
        ОформлениеСтроки.Ячейки.НаСкладе.Значение = Выборка.КоличествоОстаток;
    КонецЕсли;
КонецЦикла;
12 pessok
 
19.11.14
11:33
(10) я так понимаю, что подразумевался фильтр на показанные данные, те, что сейчас на экране. лично я не умею получать их список... научите :)
13 pessok
 
19.11.14
11:33
(11) а, чорт. элементарно же, действительно
14 Широкий
 
19.11.14
11:33
МассивСсылок=Новый Массив;
    
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        ДанныеСтроки=ОформлениеСтроки.ДанныеСтроки;
        
        МассивСсылок.Добавить(ДанныеСтроки.Ссылка);
    КонецЦикла;
    
    Запрос=Новый Запрос;
    Запрос.УстановитьПараметр("МассивСсылок",МассивСсылок);
    
    Запрос.Текст="ВЫБРАТЬ РАЗРЕШЕННЫЕ
    |    НаборнаяНакладная.Ссылка,
    |    НаборнаяНакладная.ДокументОснование.АвтомобильКросс.Наименование КАК АвтомобильКроссНаименование
    |ИЗ
    |    Документ.НаборнаяНакладная КАК НаборнаяНакладная
    |ГДЕ
    |    НаборнаяНакладная.Ссылка В(&МассивСсылок)";
    
    ТаблДанных=Запрос.Выполнить().Выгрузить();                
    
    ЦветКрасный=WebЦвета.Красный;
    
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        ДанныеСтроки=ОформлениеСтроки.ДанныеСтроки;
        Ячейки=ОформлениеСтроки.Ячейки;
        
        СтрокаПоиска=ТаблДанных.Найти(ДанныеСтроки.Ссылка,"Ссылка");
        Если СтрокаПоиска<>Неопределено Тогда
            Ячейки.АвтомобильКросс.УстановитьТекст(СтрокаПоиска.АвтомобильКроссНаименование);
        КонецЕсли;
    КонецЦикла;
15 evorle145
 
19.11.14
11:34
(11)  Понял! пробую делать
16 evorle145
 
19.11.14
12:04
Действительно стало быстрее где то на 25% судя по замеру, но соединив таблицы цен и остатков полным соединением, все-таки все равно чую что опять делаю не правильно.

    Запрос.Текст ="ВЫБРАТЬ
                  |    ЦеныНоменклатурыСрезПоследних.Номенклатура КАК НоменклатураЦ,
                  |    МАКСИМУМ(ЦеныНоменклатурыСрезПоследних.Цена) КАК ЦенаЦ
                  |ПОМЕСТИТЬ Цена
                  |ИЗ
                  |    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, Номенклатура В (&МассивСсылок)) КАК ЦеныНоменклатурыСрезПоследних
                  |ГДЕ
                  |    ЦеныНоменклатурыСрезПоследних.ТипЦен = &ТипЦен
                  |
                  |СГРУППИРОВАТЬ ПО
                  |    ЦеныНоменклатурыСрезПоследних.Номенклатура
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |    ТоварыНаСкладахОстатки.Номенклатура КАК НоменклатураО,
                  |    СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток) КАК КоличествоОстатокО
                  |ПОМЕСТИТЬ Остаток
                  |ИЗ
                  |    РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
                  |
                  |СГРУППИРОВАТЬ ПО
                  |    ТоварыНаСкладахОстатки.Номенклатура
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |    Остаток.НоменклатураО,
                  |    Цена.НоменклатураЦ,
                  |    Остаток.КоличествоОстатокО,
                  |    Цена.ЦенаЦ
                  |ПОМЕСТИТЬ Почти
                  |ИЗ
                  |    Цена КАК Цена
                  |        ПОЛНОЕ СОЕДИНЕНИЕ Остаток КАК Остаток
                  |        ПО Цена.НоменклатураЦ = Остаток.НоменклатураО
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |    ВЫБОР
                  |        КОГДА Почти.НоменклатураО ЕСТЬ NULL
                  |            ТОГДА Почти.НоменклатураЦ
                  |        ИНАЧЕ Почти.НоменклатураО
                  |    КОНЕЦ КАК Номенклатура,
                  |    Почти.КоличествоОстатокО КАК КоличествоОстаток,
                  |    Почти.ЦенаЦ КАК Цена
                  |ИЗ
                  |    Почти КАК Почти";

Помогите плиз подправить
17 Широкий
 
19.11.14
12:06
(16) На остатки - где твой фильтр?
И вообще можно сделать все одним запросом
18 Гёдза
 
19.11.14
12:11
Зачем полное соединение цен и остатков?
19 Широкий
 
19.11.14
12:12
ВЫБРАТЬ
    Результат.Номенклатура,
    МАКСИМУМ(Результат.Цена) КАК Цена,
    МАКСИМУМ(Результат.Количество) КАК Количество
ИЗ
    (ВЫБРАТЬ
        ЦеныНоменклатуры.Номенклатура КАК Номенклатура,
        ЦеныНоменклатуры.Цена КАК Цена,
        0 КАК Количество
    ИЗ
        РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
                ,
                Номенклатура В (&МассивНоменклатуры)
                    И ТипЦен = &ТипЦен
                    И ХарактеристикаНоменклатуры = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)) КАК ЦеныНоменклатуры
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        ТоварыНаСкладах.Номенклатура,
        0,
        ТоварыНаСкладах.КоличествоОстаток
    ИЗ
        РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура В (&МассивНоменклатуры)) КАК ТоварыНаСкладах) КАК Результат

СГРУППИРОВАТЬ ПО
    Результат.Номенклатура
20 GANR
 
19.11.14
12:13
(0) Совет один: убрать какие-либо запросы из этого места
21 GANR
 
19.11.14
12:15
(2) А если кто-то заведет новую номенклатуру?
22 GANR
 
19.11.14
12:16
(0) А динамический список сделать никак?
23 H A D G E H O G s
 
19.11.14
12:24
(22) Динамический список будет только хуже.
24 H A D G E H O G s
 
19.11.14
12:27
Все норм у тебя, не парься, только зачем ПолноеСоединение, а затем свертка?
25 H A D G E H O G s
 
19.11.14
12:27
Ну вернее, Объединить все, а затем Группировать
26 Поpyчик-4
 
19.11.14
12:29
(22) Скажи что поумнее. Речь идёт об обычной форме.
27 evorle145
 
19.11.14
13:06
(25) , понял, пробую объединить. (26) , да формы обычные
28 evorle145
 
19.11.14
13:13
(25) , спасибо, объединить с последующей группировкой еще на 25% быстрее стало работать. Лучше наверное уже не сделать, не вынося запрос из этого события
29 Гёдза
 
19.11.14
13:15
2 левых соединения в динамическом списке и все. И работать будет быстро достаточно. Если конечно итоги для цен включены
30 evorle145
 
19.11.14
13:16
(29) , а что имеется ввиду под динамическим списком на обычных формах?
31 Широкий
 
19.11.14
13:18
(28) я тебя в (19) написал твой запрос
32 evorle145
 
19.11.14
13:23
(31) , извините, увлекся... а вы сделали через вложенную таблицу, а я через временную , это имеет влияние на скорость выполнения запроса?
33 GANR
 
20.11.14
12:14
(23) Если связи по неиндексированным полям - то хуже, это да. Умеючи их надо использовать. Имел сомнительное удовольствие открывать форму списка 20000 документов, в которой основная таблица была соединена с 10-12 вложенными запросами - минуту висит при открытии.
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.