|
Как оптимизировать отчет? | ☑ | ||
---|---|---|---|---|
0
Anabella
16.06.15
✎
15:42
|
Отчет из таблиц SQL выгружает данные в 1с. За месяц отчет выполняется секунд 40. Нужно убыстрить. Есть код формирования скд, есть код выгрузки таблиц из скуля. Что тут можно оптимизировать? Могу скинуть сам отчет, только куда?
&НаСервере Функция ПолучитьТаблицу() Дата1 = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[0].Значение.ДатаНачала; Дата2 = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[0].Значение.ДатаОкончания; ЗапросПродаж = Новый Запрос; ЗапросПродаж.УстановитьПараметр("Дата1",Дата1); ЗапросПродаж.УстановитьПараметр("Дата2",Дата2); ЗапросПродаж.Текст = "ВЫБРАТЬ | OtchetProdazh.Ofis КАК Офисы, | OtchetProdazh.GrupTovara КАК ГруппыТоваров, | OtchetProdazh.KodTovara КАК KodTovara, | СУММА(OtchetProdazh.Vistavleno) КАК Выставлено, | СУММА(OtchetProdazh.Oplacheno) КАК Оплачено, | OtchetProdazh.Data КАК Дата |ИЗ | ВнешнийИсточникДанных.OtchetProdazh.Таблица.OtchetProdazh КАК OtchetProdazh |ГДЕ | OtchetProdazh.Data >= &Дата1 | И OtchetProdazh.Data <= &Дата2 "; Если Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[1].Использование = Истина и Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[1].ПравоеЗначение <> 7 тогда Офис = ПолучитьОфис(); ЗапросПродаж.УстановитьПараметр("Ofis","%"+Офис+"%"); ЗапросПродаж.Текст = ЗапросПродаж.Текст + "И OtchetProdazh.Ofis ПОДОБНО &Ofis "; КонецЕсли; ЗапросПродаж.Текст = ЗапросПродаж.Текст + "СГРУППИРОВАТЬ ПО | OtchetProdazh.Ofis, | OtchetProdazh.GrupTovara, | OtchetProdazh.KodTovara, | OtchetProdazh.Data | |УПОРЯДОЧИТЬ ПО | KodTovara"; РезультатЗапросаПродаж = ЗапросПродаж.Выполнить().Выгрузить(); РезультатЗапросаПродаж.Колонки.Добавить("Товары"); РезультатЗапросаПродаж.Колонки.Добавить("Соотношение"); //РезультатЗапросаПродаж.Колонки.Добавить("Дата"); кол = РезультатЗапросаПродаж.Количество(); строка=0; Пока строка < кол Цикл КодТовара = РезультатЗапросаПродаж[строка].KodTovara; Товары = Справочники.Номенклатура.НайтиПоКоду(СокрЛП(КодТовара)); Пока строка < кол И КодТовара = РезультатЗапросаПродаж[строка].KodTovara Цикл РезультатЗапросаПродаж[строка].Товары = Товары; строка = строка+1; КонецЦикла; КонецЦикла; Возврат РезультатЗапросаПродаж; КонецФункции |
|||
1
Волшебник
модератор
16.06.15
✎
15:44
|
Заведи регистр оборотов и сделай агрегат. Отчёт будет формироваться за 1 секунду.
|
|||
2
Anabella
16.06.15
✎
15:46
|
(1) в рабочую базу вмешиваться очень нежелательно. крайний вариант.
|
|||
3
MadHead
16.06.15
✎
15:50
|
вообще было бы не плохо увидеть на каких строках сколько тратиться времени. Сразу видно что последний цикл нужно заменить запросом
|
|||
4
Широкий
16.06.15
✎
15:50
|
(0) Странно, функиця есть "group by" нет
|
|||
5
MadHead
16.06.15
✎
15:51
|
так же проверить есть ли индекс по датам во внешней базе
|
|||
6
ДенисЧ
16.06.15
✎
15:51
|
(4) ЗапросПродаж.Текст = ЗапросПродаж.Текст + "СГРУППИРОВАТЬ ПО
|
|||
7
Широкий
16.06.15
✎
15:52
|
+4 неполностью посмотрел, сори.
Мне кажется "OtchetProdazh.Data" тут лишняя и с подобно надо что то делать |
|||
8
Anabella
16.06.15
✎
15:54
|
(3) 35% времени тратится на строчку ПроцессорВывода.Вывести(ПроцессорКомпоновки);
26% времени тратится на строчку РезультатЗапросаПродаж = ЗапросПродаж.Выполнить().Выгрузить(); |
|||
9
Широкий
16.06.15
✎
15:54
|
Товары = Справочники.Номенклатура.НайтиПоКоду(СокрЛП(КодТовара));
Это определенно надо в запросе делать |
|||
10
Anabella
16.06.15
✎
15:57
|
Охренеть, мне сам Волшебник отвечал! Надо сохранить себе скрин на память :-)
|
|||
11
Drac0
16.06.15
✎
15:58
|
(0) Запрос с этим условием: "И OtchetProdazh.Ofis ПОДОБНО &Ofis " ?
Ну и (3) с (9) однозначно надо. Если с типами нет косяка. |
|||
12
ДенисЧ
16.06.15
✎
15:58
|
(10) теперь неделю глаза не мой ))
|
|||
13
Anabella
16.06.15
✎
15:59
|
(11) Если стоит отбор по офисам, то добавляется это условие, если нет, то без него. В любом случае неприлично долго.
|
|||
14
Anabella
16.06.15
✎
16:00
|
(11) касательно (3) я уже ответила в (8) 2 самые долгие позиции. А касательно (9) сейчас переделываю.
|
|||
15
Anabella
16.06.15
✎
16:01
|
(12) Чуяло мое нутро, не надо было сегодня глаза красить ))
|
|||
16
Drac0
16.06.15
✎
16:05
|
(13) Поиск по параметру такого вида "%"+Офис+"%" херит все индексы. Если они там вообще есть, конечно же. Желательно искать по полному равенству. Или хотя бы знак % оставить только в конце.
|
|||
17
rsv
16.06.15
✎
16:05
|
(0) У вас внешний источник.... выгрузка просто из него данных простым селектом скажем Тор 100 сколько времени ?
|
|||
18
D_E_S_131
16.06.15
✎
16:08
|
(17) Вообще не плохо бы понимать сколько там данных во "внешнем источнике", а то там может не 100, а 100500 и 40 секунд это нормально для такого объема.
|
|||
19
rsv
16.06.15
✎
16:10
|
+(17) И мы обсуждаем "неприлично долго" работу внешнего источника ? Или обработку в цикле курсора оного с вызовом НайтиПоКоду ?
|
|||
20
Anabella
16.06.15
✎
16:17
|
(17)(18) первые 100 выбирает за 7,2 сек. Количество записей в таблице за месяц апрель к примеру - 97776.
|
|||
21
Anabella
16.06.15
✎
16:21
|
(19)Есть отчет и жалоба на него что он работает долго. Собственно я и думаю как-то его убыстрить. Отчет на двух функциях тормозит, первую я выложила, вот вторая (ссылается на функцию выше).
Если Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[1].ПравоеЗначение = 7 тогда Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[1].Использование = ложь; КонецЕсли; Результат.Очистить(); ОтчетОбъект = РеквизитФормыВЗначение("Отчет"); Схема = ОтчетОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"); Настройки = Схема.НастройкиПоУмолчанию; КомпоновщикНастроекДанных = Новый КомпоновщикНастроекКомпоновкиДанных; КомпоновщикНастроекДанных.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема)); КомпоновщикНастроекДанных.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию); КомпоновщикНастроекДанных.ЗагрузитьПользовательскиеНастройки(Отчет.КомпоновщикНастроек.ПользовательскиеНастройки); КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; Макет = КомпоновщикМакета.Выполнить(Схема, КомпоновщикНастроекДанных.ПолучитьНастройки()); ТаблицаЗаказов = ПолучитьТаблицу(); ВнешниеНаборыДанных = Новый Структура; ///присоединяем к скд наш внешний набор данных ВнешниеНаборыДанных.Вставить("Результат",ТаблицаЗаказов); ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(Макет, ВнешниеНаборыДанных); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(Результат); ПроцессорВывода.Вывести(ПроцессорКомпоновки); Элементы.Результат.ОтображениеСостояния.Видимость = Ложь; Элементы.Результат.ОтображениеСостояния.ДополнительныйРежимОтображения = ДополнительныйРежимОтображения.НеИспользовать; Результат.ПоказатьУровеньГруппировокСтрок(1); Результат.ПоказатьУровеньГруппировокСтрок(0); Офис = ПолучитьОфис(); Если Офис = "Общий" тогда ТаблицаЗаказов.Свернуть("Офисы,Дата","Оплачено"); Строка = "["; Для каждого СтрТЗ из ТаблицаЗаказов Цикл Если СтрТЗ.Офисы<>"" и СтрТЗ.Офисы <> null тогда Строка = Строка + Строка("["+Формат(СтрТЗ.Дата, "ДФ=ггггММдд") + "," + Формат(окр(СтрТЗ.Оплачено,0),"ЧГ=0")+"," + Символ(34)+СтрТЗ.Офисы+Символ(34)+"],"); КонецЕсли; КонецЦикла; Строка = Строка+"]"; Иначе ТаблицаЗаказов.Свернуть("ГруппыТоваров,Дата","Оплачено"); Строка = "["; Для каждого СтрТЗ из ТаблицаЗаказов Цикл Если СтрТЗ.ГруппыТоваров<>"" и СтрТЗ.ГруппыТоваров <> null тогда Строка = Строка + Строка("["+Формат(СтрТЗ.Дата, "ДФ=ггггММдд") + "," + Формат(окр(СтрТЗ.Оплачено,0),"ЧГ=0")+"," + Символ(34)+СтрТЗ.ГруппыТоваров+Символ(34)+"],"); КонецЕсли; КонецЦикла; Строка = Строка+"]"; КонецЕсли; Возврат Строка; |
|||
22
Anabella
16.06.15
✎
16:22
|
(19) некрасиво получилось... лучше так:
&НаСервере Функция СформироватьКнопкаНаСервере() Время = ТекущаяДата(); Если Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[1].ПравоеЗначение = 7 тогда Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[1].Использование = ложь; КонецЕсли; Результат.Очистить(); ОтчетОбъект = РеквизитФормыВЗначение("Отчет"); Схема = ОтчетОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"); Настройки = Схема.НастройкиПоУмолчанию; КомпоновщикНастроекДанных = Новый КомпоновщикНастроекКомпоновкиДанных; КомпоновщикНастроекДанных.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема)); КомпоновщикНастроекДанных.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию); КомпоновщикНастроекДанных.ЗагрузитьПользовательскиеНастройки(Отчет.КомпоновщикНастроек.ПользовательскиеНастройки); КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; Макет = КомпоновщикМакета.Выполнить(Схема, КомпоновщикНастроекДанных.ПолучитьНастройки()); ТаблицаЗаказов = ПолучитьТаблицу(); ВнешниеНаборыДанных = Новый Структура; ///присоединяем к скд наш внешний набор данных ВнешниеНаборыДанных.Вставить("Результат",ТаблицаЗаказов); ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(Макет, ВнешниеНаборыДанных); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(Результат); ПроцессорВывода.Вывести(ПроцессорКомпоновки); Элементы.Результат.ОтображениеСостояния.Видимость = Ложь; Элементы.Результат.ОтображениеСостояния.ДополнительныйРежимОтображения = ДополнительныйРежимОтображения.НеИспользовать; Результат.ПоказатьУровеньГруппировокСтрок(1); Результат.ПоказатьУровеньГруппировокСтрок(0); Офис = ПолучитьОфис(); Если Офис = "Общий" тогда ТаблицаЗаказов.Свернуть("Офисы,Дата","Оплачено"); Строка = "["; Для каждого СтрТЗ из ТаблицаЗаказов Цикл Если СтрТЗ.Офисы<>"" и СтрТЗ.Офисы <> null тогда Строка = Строка + Строка("["+Формат(СтрТЗ.Дата, "ДФ=ггггММдд") + "," + Формат(окр(СтрТЗ.Оплачено,0),"ЧГ=0")+"," + Символ(34)+СтрТЗ.Офисы+Символ(34)+"],"); КонецЕсли; КонецЦикла; Строка = Строка+"]"; Иначе ТаблицаЗаказов.Свернуть("ГруппыТоваров,Дата","Оплачено"); Строка = "["; Для каждого СтрТЗ из ТаблицаЗаказов Цикл Если СтрТЗ.ГруппыТоваров<>"" и СтрТЗ.ГруппыТоваров <> null тогда Строка = Строка + Строка("["+Формат(СтрТЗ.Дата, "ДФ=ггггММдд") + "," + Формат(окр(СтрТЗ.Оплачено,0),"ЧГ=0")+"," + Символ(34)+СтрТЗ.ГруппыТоваров+Символ(34)+"],"); КонецЕсли; КонецЦикла; Строка = Строка+"]"; КонецЕсли; Возврат Строка; КонецФункции |
|||
23
Гёдза
16.06.15
✎
16:23
|
какая строчка выполняется дольше всего?
|
|||
24
Anabella
16.06.15
✎
16:24
|
(23)
35% времени тратится на строчку ПроцессорВывода.Вывести(ПроцессорКомпоновки); 26% времени тратится на строчку РезультатЗапросаПродаж = ЗапросПродаж.Выполнить().Выгрузить(); |
|||
25
Гёдза
16.06.15
✎
16:26
|
(24) сколько в итоговом отчете строк?
|
|||
26
Anabella
16.06.15
✎
16:27
|
(9) переделала, стало дольше.
Пока строка < кол Цикл КодТовара = РезультатЗапросаПродаж[строка].KodTovara; ЗапросТовар = Новый Запрос; ЗапросТовар.Текст = "ВЫБРАТЬ | Номенклатура.Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Код = &Код"; ЗапросТовар.УстановитьПараметр("Код",КодТовара); ВыборкаТовар = ЗапросТовар.Выполнить().Выбрать(); ВыборкаТовар.Следующий(); РезультатЗапросаПродаж[строка].Товары = ВыборкаТовар.Ссылка; строка = строка+1; КонецЦикла; |
|||
27
Anabella
16.06.15
✎
16:28
|
(25)Количество записей в таблице за месяц апрель к примеру - 97776.
|
|||
28
Anabella
16.06.15
✎
16:35
|
(25)а вот выгружать из внешних источников в эксель чтобы быстренько глянуть общее количество данных явно не стоило... сижу, жду, когда отвиснет.
|
|||
29
Широкий
16.06.15
✎
16:37
|
(26) Ну ты конечно переделала :)
|
|||
30
Зеленый пень
16.06.15
✎
16:38
|
Сначал собрать все коды товаров в массив, потом сделать запрос по товарам с этим кодов - выгрузить в ТЗ (добавить ТЗ индекс по полю кода).
И в цикле искать уже по коду в ТЗ, а не делать запрос по каждой строке. |
|||
31
Anabella
16.06.15
✎
16:38
|
(29)Я старалась, спешила, пока желающие помочь не пропали) Что исправить?
|
|||
32
Anabella
16.06.15
✎
16:39
|
(30)Спасибо!
|
|||
33
Широкий
16.06.15
✎
16:39
|
(32) Не надо его благодарить - он гадость советует
|
|||
34
Anabella
16.06.15
✎
16:40
|
(33)Спасибо отменяется, кто чего хорошего посоветует?)
|
|||
35
Широкий
16.06.15
✎
16:40
|
(32) У тебя уже есть запрос из внешнего источника - в нем же через левое соединение получи номенклатуру
|
|||
36
Anabella
16.06.15
✎
16:42
|
(35)Гениально, черт побери
|
|||
37
Anabella
16.06.15
✎
16:45
|
(35)использование нескольких источников данных недопустимо, пишет (
|
|||
38
Drac0
16.06.15
✎
16:51
|
(37) Выбери сначала в ВТ из внешнего. Потом к этой ВТ уже присоединяй.
|
|||
39
Anabella
16.06.15
✎
16:53
|
(38)Ща, спасибо!
|
|||
40
Anabella
16.06.15
✎
17:00
|
(38)Та же ошибка при попытке создания временной таблицы из внешнего источника данных( Получение данных из нескольких источников недопустимо (
|
|||
41
Drac0
16.06.15
✎
17:10
|
(40) Кажется, я вспомнил, почему мы не юзаем внешние источники данных -_-
Тогда (30). Верни ему спасибо :) |
|||
42
Anabella
16.06.15
✎
17:16
|
(30) Спасибо! :-)
|
|||
43
Широкий
17.06.15
✎
09:31
|
(42) Выгрузи тогда первый запрос в таблицу значений и прогрузи ее во времянку а там левое соединение.
|
|||
44
Anabella
19.06.15
✎
11:41
|
(43)по скорости получилось примерно одинаково, но метод по (30) сработал чуть быстрее.
|
|||
45
WebberNSK
19.06.15
✎
12:23
|
(0) а вот это что такое? Офис = ПолучитьОфис();
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |