Highload-оптимизация 1С: теория и практика на примере консолидированной отчетности группы "Магнит" и розничной аптечной сети "Магнит"

0. 10 11.01.21 11:15 Сейчас в теме
Тема оптимизации 1С на больших данных бесконечная и всеобъемлющая, поскольку на производительность влияет целый ряд факторов – количество пользователей, данных, транзакций, неоптимальные запросы и т.д. Об инструментах для локализации проблем производительности и практических кейсах оптимизации рассказал Алексей Олейник, руководитель сектора автоматизации отчетности МСФО компании «Информационные технологии Магнит».

Перейти к публикации

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Repich 523 11.01.21 13:16 Сейчас в теме
И напоследок, самая последняя особенность – это ускорение производительности за счет использования циклов в одну строку. Я в это не верил, но это действительно так. Первый кусок кода работает медленнее, чем второй кусок кода в пять с лишним раз.

Можно реальный пример ускорения? Не синтетический тест с циклом со сложением.
1С говорят с отключенной отладкой не будет работать это.
8. kurpekov 41 13.01.21 10:56 Сейчас в теме
(1) Только что попробовал на разных компьютерах и серваках - где есть разница, где - нет (ну, там 5-10 процентов). Чаще всего разницы нет.
2. Ks_83 225 11.01.21 13:43 Сейчас в теме
ускорение производительности за счет использования циклов в одну строку

Колдунсвто
3. Ks_83 225 11.01.21 13:52 Сейчас в теме
Обработка не в СУБД. Я часто встречаю пример, как на слайде – когда данные выгружаются из запроса в промежуточную таблицу значений, чтобы передать их в другой запрос. Так делать не нужно. Если эта таблица значений вам на сервере 1С не нужна, не выгружайте ее из запроса – сохраняйте все во временных таблицах и передавайте их в другой запрос непосредственно через менеджер временных таблиц.

Есть мнение, что менеджера тоже лучше избегать, ибо он скидывает таблицы на диск.
11. user662404_itlexusss 10 15.01.21 13:13 Сейчас в теме
(3) Таблица значений тоже сохраняется на диск в сеансовые данные. Но это ерунда, по сравнению с временем, затрачиваемым при передачи больших ТЗ с сервера 1С на СУБД, Делается это пачками по 10 тысяч строк через BULK INSERT, но сильно легче от этого не становится. Причем пишется опять же во временную таблицу на диск.
Гораздо производительнее записать прямо на СУБД во временную таблицу, не спуская массив на сервер 1С.
4. TMV 14 12.01.21 07:22 Сейчас в теме
1. В видео беспардонно обрезали докладчика - как-то не красиво получилось.
5. TMV 14 12.01.21 07:40 Сейчас в теме
2. По чекам. Дело в этом:
ЧекККМСерии.Ссылка.ВидЦены КАК ВидЦены

а нужно:
ВЫРАЗИТЬ(ЧекККМСерии.Ссылка КАК Документ.ЧекККМ).ВидЦены КАК ВидЦены


З.Ы.
Может стоило вообще через внутреннее соединение сделать типа так:
ЧекиККМ.ВидЦены КАК ВидЦены
ИЗ
	Документ.ЧекККМ.Серии КАК ЧекККМСерии
	ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЧекиККМ КАК ЧекиККМ
	ПО ЧекККМСерии.Ссылка = ЧекиККМ.Ссылка
		И ЧекиККМ.Коррекция = ЛОЖЬ
12. user662404_itlexusss 10 15.01.21 13:27 Сейчас в теме
(5)ЧекККМСерии - это табличная часть документа ЧекККМ. В нем Ссылка всегда строго типизирована, поэтому транслятор 1С запросов на СУБД просто проигнорирует Ваше "ВЫРАЗИТЬ(...)".
Проблема была в ЧекиККМ.Ссылка, а точнее соединение по этому полю. Транслятор 1С не видел, что идет соединение с полем одного типа, поэтому интерпретировал "ПО ЧекиККМ.Ссылка = ЧекиККМСерии.Ссылка" во что-то подобное
"ON CASE WHEN ЧекиККМ.RTRef = 0x... THEN ЧекиККМ.RRef END = ЧекиККМСерии._IDRef".
В свою очередь оптимизатор MS SQL 2017 увидел слева от "ON" нелюбимую конструкцию "CASE WHEN" и решил сделать HASH JOIN вместо очевидного LOOP JOIN. Поэтому система и считала хеши по всей таблице табличной части чеков ККМ, а когда их у Вас миллиарды, хеши считаются ооооочень долго.
Оптимизатор MS SQL 2012 и ниже делал еще хуже. Подробностей не помню, но был какой-то жесткий Lazy spool.
15. triviumfan 24 19.01.21 16:05 Сейчас в теме
(12) Не верю, скуль болен или намудрили чего. Не может он интерпретировать case в соединении, если в обоих таблицах ссылка одного типа.
6. TMV 14 12.01.21 07:42 Сейчас в теме
3. По промежуточной таблице. Обычно так делают, если она подлежит некой обработке кодом, и только после (а не сразу) помещается в запрос.
13. user662404_itlexusss 10 15.01.21 13:30 Сейчас в теме
(6) Гораздо производительнее эту обработку кодом сделать в виде запроса 1С. Кто получал профильное программистское образование должны помнить, как мы реализовывали исполнение алгоритмах на разных абстракциях, вроде конечных автоматов. Так и в 1С - практически любой код можно переложить в запрос. А на больших объемах данных, обработка запросом гораздо производительнее.
7. AneJIbcuH 31 12.01.21 08:10 Сейчас в теме
Метод решения – переписать код и сделать вложенный запрос, где мы выбираем прямо из этой временной таблицы РАЗЛИЧНЫЕ Номенклатура, Характеристика. И после этого уже производим слияние с регистром сведений НоменклатураСегмента.


1С говорят, соединение с вложенным запросом - это плохо.
10. leongl 385 13.01.21 21:05 Сейчас в теме
(7)Это как в детстве говорили - это огонь, не подходи, не трогай, бойся). Важен вдумчивый подход, а не бездумное клепание временных таблиц, что автор и донес.
14. user662404_itlexusss 10 15.01.21 14:03 Сейчас в теме
(7) На самом деле, в изначальном тексте есть вложенный запрос, просто Вы его не видите. В плане выполнения же он есть: внешний запрос - это конструкция РАЗЛИЧНЫЕ, а вложенный - это соединение таблиц.
В изначальном варианте, соединялись две таблицы и на результате их соединения уже выполнялись РАЗЛИЧНЫЕ (конструкции HASH AGGREGATE или последовательно "SORT + STEAM AGGREGATE"). Причем это очень тяжелые конструкции, которые имеют дурную привычку лезть в TempDB (если ошибаются с ожидаемым количеством строк).
После оптимизации, тяжелая операция РАЗЛИЧНЫЕ выполняется на гораздо меньшем множестве строк, еще до его умножения на количество сегментов. Отличия производительности тем больше, чем больше сегментов.
Оставьте свое сообщение
Вопросы с вознаграждением