1С оптимизация на примере оптимизации бухгалтерской конфигурации

1С оптимизация на примере оптимизации бухгалтерской конфигурации

Помимо собственно наблюдения за функционированием информационной системы предприятия, мониторинг является полезным инструментом для ее оптимизации (оптимизации 1С). Так, в ходе анализа базы данных мониторинга одного из клиентов были выявлены повторяющиеся всплески загрузки процессора сервера до максимума одним и тем же пользователем на значительное время:

Помимо собственно наблюдения за функционированием информационной системы предприятия, мониторинг является полезным инструментом для ее оптимизации (оптимизации 1С). Так, в ходе анализа базы данных мониторинга одного из клиентов были выявлены повторяющиеся всплески загрузки процессора сервера до максимума одним и тем же пользователем на значительное время:

1_1_600_338.jpg

1С оптимизация

На скриншоте, с лева, по графику нагрузки на процессор, хорошо виден всплеск нагрузки. С права показан списко пользователей, которые в это время работали в системе. Как видно из списка, всплеск нагрузки создавал  пользователь Василенко_А, выполняя отчёт Оборотно Сальдовая Ведомость. В квадратных скобках показан номер строки модуля конфигурации, который выполнялся в рассматриваемый момент.
 
Строка 241 отчета соответствует коду:

 Если Ит.ВыполнитьЗапрос(Дата1, Дата2, Счет) = 0 Тогда

Первоначальное и очевидное предположение, что пользователь запускает ОСВ за большой период с разворачиванием по всем аналитикам оказалось неверным. В силу своих служебных обязанностей пользователь делает ОСВ по товарным остаткам с отбором по группе справочника номенклатуры. Рассмотрим, как реализуется 1С данный отчет и попробуем выяснить причину большой загрузки им сервера.

Открыв форму трасс и наложив фильтр по времени и по данному пользователю мы видим последовательность действий 1С:

1380_zaprosi_600_543.jpg

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

9192_plan_600_254.jpg

Анализ плана показывает, что основное время сервер затратил на объединение остатков и временной таблицы.

Попробуем избавиться от отбора по родителю справочника, написав для пользователя специализированный отчет, в котором используем следующий код:

 Ит=СоздатьОбъект("БухгалтерскиеИтоги");
 Ит.ИспользоватьСубконто(ВидыСубконто.ТМЦ,,1);
 Ит.ИспользоватьСубконто(ВидыСубконто.МестаХранения, ВыбрСклад,2);
 Ит.ВыполнитьЗапрос(Дата1, Дата2, Счет.ПолучитьЗначение(сзСчета.ТекущаяСтрока()), , ,1,,"СК");
 Ит.ВыбратьСубконто();
 Пока Ит.ПолучитьСубконто()=1 Цикл
  Если Ит.Субконто().ПринадлежитГруппе(Группа)=1 Тогда
  //выводим в отчет
  Расшифровка.Установить("Субконто2", Ит.Субконто());
  Табл.ВывестиСекцию("Строка");
  НПП=НПП+1;
  КонецЕсли;
 КонецЦикла;  

Сравним время выполнения нового отчета на тех же исходных данных:

  •     время снизилось в пять раз (с 460 секунд до 85);
  •    уменьшилась загрузка сервера во время выполнения запроса.

Эффект оптимизации 1С основан на том, что для данного клиента оказалось быстрее получить все неотрицательные остатки и отфильтровать по условию на родительскую папку, чем выполнить объединение двух больших таблиц – остатков и отбора по родителю. И эффект оптимизации 1С будет значительным в том случае, если в выбранной группе справочника у большой части элементов нет остатков или оборотов.

Статьи по теме: