Персональная страница Федора Езеева | ||||||||||||||||||
|
Есть такой отчет - книга продаж. И попросили меня привесить к нему какую-то педальку. Педальку я привесил, но в момент тестирования обратил внимание, что эта книга уж очень долго формируется. Поскольку в тот момент у меня было в наличии некоторое свободное время, я решил поковыряться с оптимизацией отчета по скорости. Первое, что должен сделать программист, желающий ускорить работу своей программы - запустить профайлер. В 1С он находится в отладчике и называется "Замер производительности". Нужно это сделать для того, чтобы наши усилия были направлены на самые медленные участки программы, то есть, туда, где можно добиться максимального эффекта. Так поступил и я. И обнаружил (и это довольно частая картина), что 95% времени выполняются два запроса. Итоговое время выполнения - около 170 секунд. Вот текст самого толстого запроса (65% времени). Второй запрос был похож на первый и сделанные в нем изменения оказались идентичными. ТЗ="Период с ДатаНачала По ДатаКон; |Фирма=Регистр.НДСприобретенныхТоваров.Поставка.Фирма; |КредДокумент=Регистр.НДСприобретенныхТоваров.Поставка; |Докум=Регистр.НДСприобретенныхТоваров.ТекущийДокумент; |НДС=Регистр.НДСприобретенныхТоваров.НДС; |ОблагаемаяБазаНДС=Регистр.НДСприобретенныхТоваров.ОблагаемаяБазаНДС; |СтавкаНДС=Регистр.НДСприобретенныхТоваров.СтавкаНДС; |КодОперации=Регистр.НДСприобретенныхТоваров.КодОперации; |Условие(Фирма=ВыбФирма); |Группировка КредДокумент; |Группировка Докум; |Условие ((КодОперации=ЗачтенНДСОплаченногоТовара) ИЛИ | (КодОперации=СписанНДСВозвращенногоНеоплаченногоТовара)); |Функция РасхНДС10= Расход(НДС) когда ((глПроцентНДС(СтавкаНДС)>0) и | (глПроцентНДС(СтавкаНДС)<=10)); |Функция РасхНДС20= Расход(НДС) когда (глПроцентНДС(СтавкаНДС)>10); |Функция БазаБезНДС= Сумма(ОблагаемаяБазаНДС) когда (глПроцентНДС(СтавкаНДС)=0); |Функция БазаНДС10= Сумма(ОблагаемаяБазаНДС) когда ((глПроцентНДС(СтавкаНДС)>0) и | (глПроцентНДС(СтавкаНДС)<=10)); |Функция БазаНДС20= Сумма(ОблагаемаяБазаНДС) когда (глПроцентНДС(СтавкаНДС)>10); Первое, на что я обратил внимание - частый вызов функции глПроцентНДС(). Смотрим ее текст. Функция глПроцентНДС(Ставка) Экспорт Если ТипЗначенияСтр(Ставка)="Справочник" Тогда Если Ставка.Вид()="СтавкиНДС" Тогда Возврат Ставка.Ставка; КонецЕсли; КонецЕсли; Возврат 0; КонецФункции Проверки - это, конечно, хорошо, но не для этого случая. Я могу быть уверенным в корректности передаваемых данных. Меняю в запросе вызов глПроцентНДС(СтавкаНДС) на СтавкаНДС.Ставка. Проверяю, время выполнения падает на 30 секунд! Думаю дальше. Сама СтавкаНДС, как элемент справочника меня не интересует - исключительно значение реквизита Ставка. Меняю объявление переменной, и все места, где ее использую. Получается такой запрос: |Фирма=Регистр.НДСприобретенныхТоваров.Поставка.Фирма; |КредДокумент=Регистр.НДСприобретенныхТоваров.Поставка; |Докум=Регистр.НДСприобретенныхТоваров.ТекущийДокумент; |НДС=Регистр.НДСприобретенныхТоваров.НДС; |ОблагаемаяБазаНДС=Регистр.НДСприобретенныхТоваров.ОблагаемаяБазаНДС; |СтавкаНДС=Регистр.НДСприобретенныхТоваров.СтавкаНДС.Ставка; |КодОперации=Регистр.НДСприобретенныхТоваров.КодОперации; |Условие(Фирма=ВыбФирма); |Группировка КредДокумент; |Группировка Докум; |Условие ((КодОперации=ЗачтенНДСОплаченногоТовара) ИЛИ | (КодОперации=СписанНДСВозвращенногоНеоплаченногоТовара)); |Функция РасхНДС10= Расход(НДС) когда ((СтавкаНДС>0) и (СтавкаНДС<=10)); |Функция РасхНДС20= Расход(НДС) когда (СтавкаНДС>10); |Функция БазаБезНДС= Сумма(ОблагаемаяБазаНДС) когда (СтавкаНДС=0); |Функция БазаНДС10= Сумма(ОблагаемаяБазаНДС) когда ((СтавкаНДС>0) и (СтавкаНДС<=10)); |Функция БазаНДС20= Сумма(ОблагаемаяБазаНДС) когда (СтавкаНДС>10); Ускорение составляет еще около 30-ти секунд! Вместо 168 секунд отчет строится теперь за 108. Иду далее. В типовых частенько в условиях используется не оператор ИЛИ, а проверяется попадание в список значений. Пробую сделать так: КодыОпераций=СоздатьОбъект("СписокЗначений"); КодыОпераций.ДобавитьЗначение(ЗачтенНДСОплаченногоТовара); КодыОпераций.ДобавитьЗначение(СписанНДСНеоплаченногоТовара);, а в запросе Условие теперь выглядит так: |Условие (КодОперации в КодыОпераций);Ускорение еще на 10 секунд! Воодушевленный этим успехом, захотел и ставки НДС раскидать по спискам значений. Делаю таким образом:
И в заключение, мне не понравилась группировка "Докум". У нас ведь есть предопределенная группировка "Документ".
Это правда потребовало легких изменений в модуль обхода по запросу, но после приведения запроса к такому виду:
| |||||||||||||||||
![]() © 1998-2004 Fedor Ezeev. |