Имя: Пароль:
1C
1С v8
Оптимизация запроса
,
0 demart-omsk
 
10.12.12
08:10
Задача: Нужно сформировать отчет, показывающей накопления покупателей по ДК ( накопления считаются по заказам (плюс) отказ от заказа (минус)). Отчет работает верно, но долго, 1500 ДК проверяет на накопления 5 мин.
Помогите с оптимизацией запроса.

       запрос1 = Новый Запрос;
       запрос1.Текст=
       "ВЫБРАТЬ
       |    ЗаказыПокупателейОбороты.ЗаказПокупателя.ДисконтнаяКарта КАК ЗаказПокупателяДисконтнаяКарта,
       |    ЗаказыПокупателейОбороты.ЗаказПокупателя.Контрагент КАК ЗаказПокупателяКонтрагент
       |ИЗ
       |    РегистрНакопления.ЗаказыПокупателей.Обороты КАК ЗаказыПокупателейОбороты
       |
       |УПОРЯДОЧИТЬ ПО
       |    ЗаказПокупателяКонтрагент
       |АВТОУПОРЯДОЧИВАНИЕ";
       
       результат1=запрос1.Выполнить();
       выгрузка1=результат1.Выгрузить();
       выгрузка1.Свернуть("ЗаказПокупателяДисконтнаяКарта, ЗаказПокупателяКонтрагент" );
       для каждого стр1 из выгрузка1 цикл
           если стр1.ЗаказПокупателяДисконтнаяКарта.кодКарты <> "" тогда
               запрос = Новый Запрос;
               запрос.УстановитьПараметр("ДК", стр1.ЗаказПокупателяДисконтнаяКарта);
               запрос.УстановитьПараметр("ПричинаЗакрытияЗаказа", Справочники.ПричиныЗакрытияЗаказов.НайтиПоНаименованию("Отказ от заказа"));
               запрос.Текст=
               "ВЫБРАТЬ
               |    NULL КАК ПричинаЗакрытияЗаказа,
               |    ЗаказыПокупателейОбороты.СуммаВзаиморасчетовПриход КАК СуммаВзаиморасчетов,
               |    ЗаказыПокупателейОбороты.ЗаказПокупателя.ДисконтнаяКарта КАК ЗаказДисконтнаяКарта,
               |    ЗаказыПокупателейОбороты.ЗаказПокупателя.Контрагент
               |ИЗ
               |    РегистрНакопления.ЗаказыПокупателей.Обороты(, , , ЗаказПокупателя.ДисконтнаяКарта = &ДК) КАК ЗаказыПокупателейОбороты
               |ГДЕ
               |    ЗаказыПокупателейОбороты.ЗаказПокупателя.ДисконтнаяКарта = &ДК
               |    И ЗаказыПокупателейОбороты.ЗаказПокупателя.Проведен
               |    И (НЕ ЗаказыПокупателейОбороты.ЗаказПокупателя.ПометкаУдаления)
               |
               |ОБЪЕДИНИТЬ ВСЕ
               |
               |ВЫБРАТЬ
               |    ПричиныЗакрытияЗаказов.ПричинаЗакрытияЗаказа,
               |    -ПричиныЗакрытияЗаказов.СуммаВзаиморасчетов,
               |    ПричиныЗакрытияЗаказов.Заказ.ДисконтнаяКарта,
               |    ПричиныЗакрытияЗаказов.Заказ.Контрагент
               |ИЗ
               |    РегистрСведений.ПричиныЗакрытияЗаказов КАК ПричиныЗакрытияЗаказов
               |ГДЕ
               |    ПричиныЗакрытияЗаказов.Заказ.ДисконтнаяКарта = &ДК
               |    И ПричиныЗакрытияЗаказов.ПричинаЗакрытияЗаказа = &ПричинаЗакрытияЗаказа
               |    И ПричиныЗакрытияЗаказов.Заказ.Проведен
               |    И (НЕ ПричиныЗакрытияЗаказов.Заказ.ПометкаУдаления)
               |ИТОГИ ПО
               |    ОБЩИЕ";
               результат=запрос.Выполнить();
               выгрузка=результат.Выгрузить();
               СуммаПродаж = 0;
               Для каждого стр из выгрузка цикл
                   если ТипЗнч(стр.СуммаВзаиморасчетов) <> Тип("Null") тогда
                       СуммаПродаж = СуммаПродаж + стр.СуммаВзаиморасчетов;
                   КонецЕсли;
               КонецЦикла;
               Если СуммаПродаж <> 0  тогда    
                   ОбластьСтроки.Параметры.контрагент = стр1.ЗаказПокупателяКонтрагент;
                   ОбластьСтроки.Параметры.ДК = стр1.ЗаказПокупателяДисконтнаяКарта;
                   ОбластьСтроки.Параметры.Сумма = СуммаПродаж;
                   ТабДокумент.Вывести(ОбластьСтроки);
               КонецЕсли;
           КонецЕсли;
       КонецЦикла;
1 perec1982
 
10.12.12
08:13
Тебя интересуют накопления за весь период?
2 Нуф-Нуф
 
10.12.12
08:13
Ужаснах
3 demart-omsk
 
10.12.12
08:13
да, за весь период
4 dmpl
 
10.12.12
08:14
(0) Запрос в цикле - это святотатство. Сделай 1 запрос, а потом результат в цикле обходи.
5 demart-omsk
 
10.12.12
08:15
в 1 запросеь он же все взаиморасчеты к 1му сведет
6 dmpl
 
10.12.12
08:16
(0) Хотя в данном случае можно сразу в результате нужный запрос получить.
7 demart-omsk
 
10.12.12
08:16
мне нужно по каждой ДК взаиморасчеты вычислить
8 dmpl
 
10.12.12
08:17
(7) Сделай группировку и итоги по ДК.
9 demart-omsk
 
10.12.12
08:29
dmpl, спс
10 kosts
 
10.12.12
08:30
Самое лучшее это конечно сделать все в одном запросе.

Если корректировать эту процедуру, то

запрос1 - сворачивать сразу в запросе.
Не выгружать в ТЗ, а обходить строки выборки запроса.
стр1.ЗаказПокупателяДисконтнаяКарта.кодКарты - получить кодКарты в запросе.

Проверки на Проведен и ПометкаУдаления скорее всего не нужно делать, т.к. если есть движения в регистре, то регистратор по любому проведен.

Справочники.ПричиныЗакрытияЗаказов.НайтиПоНаименованию("Отказ от заказа") - вынести во вне цикла

СуммаПродаж - получать в запросе.
11 kosts
 
10.12.12
08:34

|ИТОГИ ПО
|    ОБЩИЕ";

если ТипЗнч(стр.СуммаВзаиморасчетов) <> Тип("Null") тогда


вот тут скорее всего косяк: формируешь дерево, а затем борешься с ним отлавливая только макушку. Замени итоги на группировку
12 kosts
 
10.12.12
08:38
Создание второго запроса вынеси за цикл.
Достаточно только задавать параметр.
13 demart-omsk
 
10.12.12
08:39
спс, за советы, буду пробывать
14 kosts
 
10.12.12
09:08
в первом приближении как-то так должно быть


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

   |ОБЪЕДИНИТЬ ВСЕ

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

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

Пока Выборка.Следующий() Цикл
   ОбластьСтроки.Параметры.Заполнить(Выборка);
   ТабДокумент.Вывести(ОбластьСтроки);
КонецЦикла;



тренируйся запросы делать
15 kosts
 
10.12.12
09:12
(14)
|где СуммаВзаиморасчетов > 0 => |где Сумма > 0
16 Maxus43
 
10.12.12
09:18
|ГДЕ
               |    ЗаказыПокупателейОбороты.ЗаказПокупателя.ДисконтнаяКарта = &ДК
               |    И ЗаказыПокупателейОбороты.ЗаказПокупателя.Проведен
               |    И (НЕ ЗаказыПокупателейОбороты.ЗаказПокупателя.ПометкаУдаления)

это всё в топку