Не думать о секундах свысока...

21.05.19

База данных - HighLoad оптимизация

Несколько примеров оптимизации типовой конфигурации УТ11. Описанные приемы подходят для многих других конфигураций.

 

 
 1. Справочники.УпаковкиЕдиницыИзмерения.ТекстЗапросаКоэффициентаУпаковки()

Обратите на текст запроса, который возвращает эта функция. В типовой УТ он используется порядка 500 раз. Его добавляют в отчеты, модули документов и так далее. Думаю, Вы уже догадались, если организация торгует штучным товаром и не объединяет товар в упаковки, то этот запрос просто возвращает число 1. Функциональная опция «ИспользоватьУпаковкиНоменклатуры», на подстановку не влияет.

Например, при формировании запроса по подбору заменил строки кода

ШаблонТекстаЗапроса = СтрЗаменить(ШаблонТекстаЗапроса,"&ТекстЗапросаКоэффициентУпаковки1", 
Справочники.УпаковкиЕдиницыИзмерения.ТекстЗапросаКоэффициентаУпаковки("ЦеныНоменклатуры.Упаковка","ЦеныНоменклатуры.Номенклатура"));

На код

ШаблонТекстаЗапроса = СтрЗаменить(ШаблонТекстаЗапроса,"&ТекстЗапросаКоэффициентУпаковки1",1);

и подбор товаров стал работать в два раза быстрее.

Если Вам будет интересно, я напишу обработку для проверки – можно ли в Вашей базе заменить текст запроса на 1.

 
 2. Работа над ошибками

Понятно, что регистрация и обработка ошибки занимает определенное время поэтому необходимо ежедневно просматривать журнал регистрации и технологический журнал, непримиримо устранять источники ошибок. Воспользуемся результатами статьи //infostart.ru/public/825405/ пункт «Наиболее частые ошибки»

При анализе технологического журнала было выявлено много событий EXCP (Например, до 11 тысяч в час). Сравнил с журналом регистрации, выяснил — это фоновые задания, которые запускаются, например при «Быстром поиске» в списке заказов, в списке номенклатуры а затем прерываются: пользователь не дождался. В журнале регистрации фоновое задание отменено или прервано.

Очевидно, что незавершенных фоновых заданий должно быть меньше, а пользователи должны принимать решение о поиске более ответственно. Оптимизация динамического списка – в следующем пункте.

Кстати, некоторые RLS ограничения тоже выглядят лишними. В технологическом журнале их можно искать по слову "DUMMY".

 
 3. Динамические списки

Нужно отключать типовой поиск, который запускает фоновые задание. Кроме этого, обязательно нужно ограничивать период (для списка документов). Журнал документов за месяц открывается в двенадцать раз быстрее, чем за год. Динамическое считывание отключил: лучше один большой запрос, чем много маленьких. Все изменения нужно делать не в форме, а в коде. В общем, предлагаю такой вид процедуры в форме списка:

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Элементы.Список.ПоискПриВводе = ПоискВТаблицеПриВводе.Авто;
Элементы.Список.ПоложениеСтрокиПоиска = ПоложениеСтрокиПоиска.Нет;       
Элементы.Список.Период.ДатаНачала = ДобавитьМесяц( ТекущаяДата(), -1 );
Элементы.Список.Период.ДатаОкончания = ДобавитьМесяц( ТекущаяДата(), 1 );
Список.ДинамическоеСчитываниеДанных = Ложь;

...
КонецПроцедуры

Для списка справочника номенклатуры потребовалось изменить модуль менеджера:

Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)

Если Параметры.Свойство("СтрокаПоиска")
И ТипЗНЧ("Параметры.СтрокаПоиска") = Тип("Строка")
И СтрДлина(Параметры.СтрокаПоиска) = 1 Тогда

СтандартнаяОбработка = Ложь;
Возврат;            
КонецЕсли;

...
КонецПроцедуры

При вводе одной буквы в списке теперь не запускается фоновое задание, а появляется окошко поиска. Добавление кода лучше видно при обновлении, чем изменение визуальной формы. Если работаете с расширениями конфигурации – используйте расширение. Не забудьте указать правильное имя элемента формы-списка и протестировать.

 
 4. Давно мечтал о инструменте, который бы находил в конфигурации все объектные чтения

И наконец моя мечта сбылась !! Как известно, при объектном чтении элемента справочника программа 1С считывает и кеширует все реквизиты. Запрос в формате SDBL имеет вид: «SELECT ID, Version, Marked, PredefinedID…». Объектные чтения, которые происходят в форме элемента в событии ПриЧтенииНаСервере() неизбежны, но имеют другой формат запроса. Воспользуемся результатами статьи //infostart.ru/public/825405/ - с помощью GIT BASH суммируем все контексты по таким запросам.

Как он работает пошагово – рассказывал в упомянутой статье, повторяться не буду. Специалисты, которые профессионально занимаются анализом технологического журнала, используют свои привычные скрипты. Они тоже смогут воспользоваться этими результатами: достаточно добавить фильтр по тексту запроса. Простая идея, но подобных примеров поиска не встречал. В своей базе нашел несколько случаев объектного чтения и с удовольствием их устранил.

 
 5. Поиск запросов, поля которых имеют тип «ХранилищеЗначений».

Как Вы понимаете, такие запросы работают без ошибок на уровне СУБД и на уровне 1С, но если полученные поля типа хранилище значений не используются, то трафик СУБД-1С можно уменьшить.

Сначала в программе 1С выберем SDBL-имена для полей типа хранилище значений. У меня получился примерно такой код для внешней обработки:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

ПоляТипаХранилище = "";
СтруктураБазы = ПолучитьСтруктуруХраненияБазыДанных();
Для каждого СтрокаСтруктурыБазы Из СтруктураБазы Цикл
Для каждого СтрокаСтруктурыПолей Из СтрокаСтруктурыБазы.Поля Цикл
СтрокаТЧ = Объект.ТабличнаяЧасть1.Добавить();
СтрокаТЧ.ИмяТаблицыХранения = СтрокаСтруктурыБазы.ИмяТаблицыХранения;
ЗаполнитьЗначенияСвойств(СтрокаТЧ, СтрокаСтруктурыПолей);    
Если СтрНайти(СтрокаСтруктурыБазы.Метаданные, "Справочник.") > 0
И СтрНайти(СтрокаСтруктурыБазы.Метаданные, "ТабличнаяЧасть") = 0
И СтрокаСтруктурыПолей.ИмяПоля <> "" Тогда

ИмяСправочника = СтрЗаменить(СтрокаСтруктурыБазы.Метаданные, "Справочник.", "");
МетаСправочник = Метаданные.Справочники[ИмяСправочника];
Реквизит= МетаСправочник.Реквизиты.Найти(СтрокаСтруктуры.ИмяПоля);
Если Реквизит <> Неопределено
И Реквизит.Тип.СодержитТип( Тип("ХранилищеЗначения") ) Тогда

ПоляТипаХранилище = ПоляТипаХранилище + ?(ПоляТипаХранилище="","","|") + СтрокаСтруктуры.ИмяПоляХранения; 
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Объект.ПоляХранилищ = "cat *.* | egrep '\.(" + ПоляТипаХранилище + ")\b' --color -A3 -B3";        

КонецПроцедуры

Итоговая строка имеет вид cat *.* | egrep '\.( ПоляТипаХранилище)\b' --color -A3 -B3 Копируем в командную строку GIT BASH и запускаем.

 
 6. ПодборТоваровСервер.ЕстьЗначенияЦенПозжеДатыПодбора()

В этой функции запрос к таблице периодического регистра будет быстрее запроса к срезу последних.

ВЫБРАТЬ РАЗРЕШЕННЫЕ
    МАКСИМУМ(Цены.Период) КАК Период
ИЗ
    РегистрСведений.ЦеныНоменклатуры КАК Цены
ГДЕ
    Цены.ВидЦены В(&ВидыЦен)

В регистре ЦеныНоменклатуры включено использование Среза последних. Поэтому запросы используют разные таблицы данных в качестве источника. Для измерения «ВидЦены» включен признак «Ведущее», поэтому индексирование недоступно, индекс в регистре существует, НО индекс в таблице среза НЕ существует, о чем честно написано в документации https://its.1c.ru/db/metod8dev/content/1590/hdoc. Поэтому любые отборы по второму (третьему) измерению без условий на предыдущие измерения в таблице среза цен вызывают сканирование таблицы. Это нужно иметь ввиду.

 

 
 7. Открытое письмо 1С:Эксперту и хорошему человеку Виктору Богачеву

 

 

P.S. На логотипе статьи часы с подводной лодки. Символизируют секунды. Мой коллега плавал.

См. также

Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы

HighLoad оптимизация Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Анализ простого плана запроса. Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы.

13.03.2024    2979    spyke    26    

42

Быстродействие типовой 1С

HighLoad оптимизация Платформа 1С v8.3 Бесплатно (free)

Оказывается, в типовых конфигурациях 1С есть, что улучшить!

13.03.2024    5109    vasilev2015    19    

37

Анализируем SQL сервер глазами 1С-ника

HighLoad оптимизация Инструменты администратора БД Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Обработка для простого и удобного анализа настроек, нагрузки и проблем с SQL сервером с упором на использование оного для 1С. Анализ текущих зааросов на sql, ожиданий, конвертация запроса в 1с и рекомендации где может тормозить

1 стартмани

15.02.2024    7638    158    ZAOSTG    68    

96

Удаление строк из таблицы значений различными способами с замером производительности

HighLoad оптимизация Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Встал вопрос: как быстро удалить строки из ТЗ? Рассмотрел пять вариантов реализации этой задачи. Сравнил их друг с другом на разных объёмах данных с разным процентом удаляемых строк. Также сравнил с выгрузкой с отбором по структуре.

09.01.2024    5977    doom2good    48    

63

Опыт оптимизации 1С на PostgreSQL

HighLoad оптимизация Бесплатно (free)

При переводе типовой конфигурации 1C ERP/УТ/КА на PostgreSQL придется вложить ресурсы в доработку и оптимизацию запросов. Расскажем, на что обратить внимание при потерях производительности и какие инструменты/подходы помогут расследовать проблемы после перехода.

20.11.2023    8871    ivanov660    6    

76

ТОП проблем/задач у владельцев КОРП лицензий 1С на основе опыта РКЛ

HighLoad оптимизация Бесплатно (free)

Казалось бы, КОРП-системы должны быть устойчивы, быстры и надёжны. Но, работая в рамках РКЛ, мы видим немного другую картину. Об основных болевых точках КОРП-систем и подходах к их решению пойдет речь в статье.

15.11.2023    5105    a.doroshkevich    20    

72

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16185    skovpin_sa    14    

98
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. rom-x 152 22.05.19 09:52 Сейчас в теме
При раскрытии 2-5 пунктов пусто
2. vasilev2015 2686 22.05.19 10:02 Сейчас в теме
Здравствуйте !

Использовал спойлеры как заголовки потому что они заметные.

За спойлеры 1 и 6 спрятал код из типовой конфигурации, чтобы он не занимал место.

Остальные спойлеры не знаю, чем занять.
3. e][tend 22.05.19 10:53 Сейчас в теме
(0) По тексту статьи, сразу было понятно чья школа. 7 пункт подтвердил догадки!
Сейчас сам прохожу обучение у Виктора)
4. kuzyara 1900 22.05.19 11:22 Сейчас в теме
5. Поиск запросов, поля которых имеют тип «ХранилищеЗначений».
но полученные поля типа хранилище значений Вы не сможете использовать из выборки запроса. Значит, трафик СУБД-1С можно уменьшить.

Почему это не сможем?
	Запрос = Новый Запрос;
	Запрос.Текст =
		"ВЫБРАТЬ ПЕРВЫЕ 10
		|	ФайлыСНеизвестнымиПараметрами.ИмяФайла КАК ИмяФайла,
		|	ФайлыСНеизвестнымиПараметрами.ФайлДанных КАК ФайлДанных,
		|	ФайлыСНеизвестнымиПараметрами.ДатаЗагрузкиФайла КАК ДатаЗагрузкиФайла
		|ИЗ
		|	РегистрСведений.ФайлыСНеизвестнымиПараметрами КАК ФайлыСНеизвестнымиПараметрами";
	Выборка = Запрос.Выполнить().Выбрать();
	
	Пока Выборка.Следующий() Цикл
			// получение в запросе реквизита типа ХранилищеЗначений
			// приводит к свопу во временный каталог сразу по всем записям
			ДвДанные = Выборка.ФайлДанных.Получить(); 
Показать

Вызов метода Выборка.ФайлДанных.Получить() не вызывает обращения к БД.
SlavaKron; +1 Ответить
5. vasilev2015 2686 22.05.19 11:37 Сейчас в теме
(4) Здравствуйте !

Изменил формулировку на компромиссную. Спасибо за внимательность.
10. kuzyara 1900 24.05.19 04:23 Сейчас в теме
(5)
Изменил формулировку на компромиссную. Спасибо за внимательность.

С таким подходом на эксперта сложно будет сдать.
mitia.mackarevich; +1 Ответить
11. vasilev2015 2686 24.05.19 08:35 Сейчас в теме
(10)

Компромисс — это искусство разделить пирог так, чтобы каждый был уверен, что лучший кусок достался ему.
6. SlavaKron 22.05.19 11:40 Сейчас в теме
(4) Зачем бы такой тип нужен был тогда. Может это актуально для запросов динамических списков, но я что-то сомневаюсь, что список будет тянуть ХЗ с сервера.
7. vasilev2015 2686 22.05.19 11:50 Сейчас в теме
(6) Здравствуйте !

Это в контексте поиска ошибок.

Ведь кто-то пишет запросы типа " Выбрать * ИЗ * " и не только в динамических списках.
8. RustIG 1351 23.05.19 09:38 Сейчас в теме
9. vasilev2015 2686 23.05.19 14:35 Сейчас в теме
(8) Здравствуйте !

Надеюсь, кому-то пригодится.
12. AlexeyT1978 202 29.05.19 17:41 Сейчас в теме
уже внедрил п.1 себе в конфу, хороший мануал
13. vasilev2015 2686 29.05.19 19:23 Сейчас в теме
(12) Здравствуйте !

У вас сколько пользователей ?
Долго подбор открывался ?
14. AlexeyT1978 202 04.06.19 16:20 Сейчас в теме
15. vasilev2015 2686 04.06.19 16:33 Сейчас в теме
16. morin 57 15.06.19 21:40 Сейчас в теме
Думаю, никто не будет против, если я немного дополню список:
- отключаем заполнение объектов по статистике (такое заполнение нужно очень не многим, но сильно затормаживает систему), необходимо поставить заглушку в ЗаполнениеСвойствПоСтатистикеПереопределяемый.ПриОпределенииЗначенияРеквизитаПоСтатистике(): СтандартнаяОбработка = Ложь;
- присмотритесь к функции ПродажиСервер.ПолучитьОтветственногоПоСкладу(), вызывается при инициализации реализации и заполняет необязательный реквизит Отпустил и ОтпустилДолжность примерными значениями, тоже польза не соответствует издержкам.
17. acanta 15.06.19 21:45 Сейчас в теме
Почему заполнение по статистике реализовано через запрос, а не при помощи записи в регистр сведений фоновым заданием?
18. vasilev2015 2686 18.06.19 08:59 Сейчас в теме
(17) Здравствуйте, Анна !

что значит "заполнение по статистике" ?
19. acanta 18.06.19 09:16 Сейчас в теме
Я имею ввиду не статистику СУБД, а тормоза при вводе нового документа из за обращения к базе.
20. morin 57 20.06.19 08:30 Сейчас в теме
(19) Он не в курсе.
vasilev2015; acanta; +2 Ответить
21. vasilev2015 2686 20.06.19 14:51 Сейчас в теме
(20) ага, догадался. От модуля "ЗаполнениеСвойствПоСтатистикеПереопределяемый" я еще не успел пострадать. Возьму на заметку.
Оставьте свое сообщение