
1С оптимизация на примере оптимизации бухгалтерской конфигурации
Помимо собственно наблюдения за функционированием информационной системы предприятия, мониторинг является полезным инструментом для ее оптимизации (оптимизации 1С). Так, в ходе анализа базы данных мониторинга одного из клиентов были выявлены повторяющиеся всплески загрузки процессора сервера до максимума одним и тем же пользователем на значительное время:
Помимо собственно наблюдения за функционированием информационной системы предприятия, мониторинг является полезным инструментом для ее оптимизации (оптимизации 1С). Так, в ходе анализа базы данных мониторинга одного из клиентов были выявлены повторяющиеся всплески загрузки процессора сервера до максимума одним и тем же пользователем на значительное время:
1С оптимизация
На скриншоте, с лева, по графику нагрузки на процессор, хорошо виден всплеск нагрузки. С права показан списко пользователей, которые в это время работали в системе. Как видно из списка, всплеск нагрузки создавал пользователь Василенко_А, выполняя отчёт Оборотно Сальдовая Ведомость. В квадратных скобках показан номер строки модуля конфигурации, который выполнялся в рассматриваемый момент.
Строка 241 отчета соответствует коду:
Если Ит.ВыполнитьЗапрос(Дата1, Дата2, Счет) = 0 Тогда
Первоначальное и очевидное предположение, что пользователь запускает ОСВ за большой период с разворачиванием по всем аналитикам оказалось неверным. В силу своих служебных обязанностей пользователь делает ОСВ по товарным остаткам с отбором по группе справочника номенклатуры. Рассмотрим, как реализуется 1С данный отчет и попробуем выяснить причину большой загрузки им сервера.
Открыв форму трасс и наложив фильтр по времени и по данному пользователю мы видим последовательность действий 1С:
1) создание временной таблицы для хранения идентификаторов субконто и их типов
CREATE TABLE #SCID( CORR TINYINT,VSC INTEGER,SC CHAR(13), PRIMARY KEY( CORR, VSC, SC ) )
2) заполнение ее аналитикой (товарами, подчиненными выбранной группе)
DECLARE @SCID CHAR(13)
IF EXISTS ( SELECT * FROM SC148 WHERE ID=' 3GX ' AND ISFOLDER=1 ) BEGIN
INSERT INTO #SCID SELECT 0, CASE WHEN ISFOLDER=2 THEN 367 ELSE -367 END, ID FROM SC148 WHERE PARENTID=' 3GX '
WHILE 1=1 BEGIN
SELECT @SCID=MAX(SC) FROM #SCID WHERE CORR=0 AND VSC=-367
IF @SCID IS NULL BREAK
INSERT INTO #SCID SELECT 0, CASE WHEN ISFOLDER=2 THEN 367 ELSE -367 END, ID FROM SC148 WHERE PARENTID=SUBSTRING(@SCID, 1, 9)
DELETE FROM #SCID WHERE CORR=0 AND VSC=-367 AND SC=@SCID
END
END
ELSE
INSERT #SCID VALUES( 0, 367, ' 3GX ' )
3) Выполнение собственно запроса
SELECT ACCID,CURRID,FLAGS=MAX(FLAGS),SC0,SC1,SC2,SUM_=SUM(SUM_),CURSUM=SUM(CURSUM),AMOUNT=SUM(AMOUNT)
FROM
(
SELECT ACCID,CURRID,FLAGS,SC0=CASE WHEN VSC0=338 THEN SC0 WHEN VSC1=338 THEN SC1 WHEN VSC2=338 THEN SC2 ELSE ' ' END
,SC1=CASE WHEN VSC0=367 THEN SC0 WHEN VSC1=367 THEN SC1 WHEN VSC2=367 THEN SC2 ELSE ' ' END
,SC2=CASE WHEN VSC0=368 THEN SC0 WHEN VSC1=368 THEN SC1 WHEN VSC2=368 THEN SC2 ELSE ' ' END
,SUM_=CASE KIND WHEN '1' THEN SD+(OBDT1-OBKT1)+(OBDT2-OBKT2) ELSE 0 END,CURSUM=CASE KIND WHEN '2' THEN SD+(OBDT1-OBKT1)+(OBDT2-OBKT2) ELSE 0 END,AMOUNT=CASE KIND WHEN '3' THEN SD+(OBDT1-OBKT1)+(OBDT2-OBKT2) ELSE 0 END
FROM ( SELECT ID FROM _1SACCS(NOLOCK INDEX=CODE) WHERE PLANID=334 AND SCHKOD>='28.1.' AND substring(SCHKOD,1,5)='28.1.' AND (SC0 = 338 OR SC1 = 338 OR SC2 = 338)
AND (SC0 = 367 OR SC1 = 367 OR SC2 = 367)
AND (SC0 = 368 OR SC1 = 368 OR SC2 = 368)
) AS DT, #SCID DTSC1,_1SBKTTL BKTTL(NOLOCK)
WHERE DATE='20081001' AND ACCID=DT.ID AND ( BKTTL.VSC0=338 OR BKTTL.VSC1=338 OR BKTTL.VSC2=338 )
AND ( DTSC1.CORR=0 AND DTSC1.VSC=367 AND ( BKTTL.VSC0=367 AND BKTTL.SC0=DTSC1.SC
OR BKTTL.VSC1=367 AND BKTTL.SC1=DTSC1.SC
OR BKTTL.VSC2=367 AND BKTTL.SC2=DTSC1.SC
) )
AND ( BKTTL.VSC0=368 OR BKTTL.VSC1=368 OR BKTTL.VSC2=368 )
AND (KIND = '1' OR KIND = '2' OR KIND = '3')
) AS SD
GROUP BY ACCID,CURRID,SC0,SC1,SC2
HAVING SUM(SUM_)<>0 OR SUM(CURSUM)<>0 OR SUM(AMOUNT)<>0
Анализ плана показывает, что основное время сервер затратил на объединение остатков и временной таблицы.
Попробуем избавиться от отбора по родителю справочника, написав для пользователя специализированный отчет, в котором используем следующий код:
Ит=СоздатьОбъект("БухгалтерскиеИтоги");
Ит.ИспользоватьСубконто(ВидыСубконто.ТМЦ,,1);
Ит.ИспользоватьСубконто(ВидыСубконто.МестаХранения, ВыбрСклад,2);
Ит.ВыполнитьЗапрос(Дата1, Дата2, Счет.ПолучитьЗначение(сзСчета.ТекущаяСтрока()), , ,1,,"СК");
Ит.ВыбратьСубконто();
Пока Ит.ПолучитьСубконто()=1 Цикл
Если Ит.Субконто().ПринадлежитГруппе(Группа)=1 Тогда
//выводим в отчет
Расшифровка.Установить("Субконто2", Ит.Субконто());
Табл.ВывестиСекцию("Строка");
НПП=НПП+1;
КонецЕсли;
КонецЦикла;
Сравним время выполнения нового отчета на тех же исходных данных:
- время снизилось в пять раз (с 460 секунд до 85);
- уменьшилась загрузка сервера во время выполнения запроса.
Эффект оптимизации 1С основан на том, что для данного клиента оказалось быстрее получить все неотрицательные остатки и отфильтровать по условию на родительскую папку, чем выполнить объединение двух больших таблиц – остатков и отбора по родителю. И эффект оптимизации 1С будет значительным в том случае, если в выбранной группе справочника у большой части элементов нет остатков или оборотов.
Статьи по теме:
- Блокировки 1С или что тормозит работу 1С? Почему медленно работает и зависает 1С?
- Сравнение PerfExpert от Софтпоинт и 1С ЦУП (центр управления производительностью) входящий в 1С КИП (корпоративный инструментальный пакет)
- Аудит производительности 1С: почему висит 1С, почему вылетает 1С - все проблемы 1С