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

20.12.23

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

В данной публикации показаны замеры производительности при работе с различными объемами данных, делается сравнение между двумя вариантами: работа через выборку и через таблицу значений.

Скачать исходный код

Наименование Файл Версия Размер
Производительность: особенности применения таблиц значений при работе с выборками данных:
.epf 9,09Kb
0
.epf 9,09Kb Скачать

Коллеги, здравствуйте!

Стал интересен момент падения производительности при работе с таблицей значения при обработке данных. Цель - выявить принцип, которого в дальнейшем следует придерживаться. 

Чем руководствовался:

1. Обработка больших объемов данных занимает много времени;

2. Создание дополнительных объектов (речь про таблицу значений) - это накладные расходы, что влияет на производительность (в худшую сторону);

3. "Да, таблица значений - это зло, но это удобно и хочется понимать, сколько это стоит".

 

Начнем

Нам нужны данные и чтоб можно было утверждать, что их объем является достаточно большим (все очень условно). Я взял таблицу продаж.

Вот формирование запроса:

Функция ПолучитьЗапрос() 
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	               |	Продажи.Период,
	               |	Продажи.Регистратор,
	               |	Продажи.НомерСтроки,
	               |	Продажи.Активность,
	               |	Продажи.Номенклатура,
	               |	Продажи.ХарактеристикаНоменклатуры,
	               |	Продажи.ЗаказПокупателя,
	               |	Продажи.ДоговорКонтрагента,
	               |	Продажи.ДокументПродажи,
	               |	Продажи.Подразделение,
	               |	Продажи.Проект,
	               |	Продажи.Организация,
	               |	Продажи.Контрагент,
	               |	Продажи.Акция,
	               |	Продажи.Количество,
	               |	Продажи.Стоимость,
	               |	Продажи.СтоимостьБезСкидок,
	               |	Продажи.НДС
	               |ИЗ
	               |	РегистрНакопления.Продажи КАК Продажи
	               |ГДЕ
	               |	Продажи.Период >= &ДатаНачала
	               |	И Продажи.Период <= &ДатаОкончания";
	Возврат Запрос;
	
КонецФункции

 

Условно выбираем период и делаем нарезки:

  1. сначала выбираем данные за первый день из периода;
  2. потом за 2 первых дня;
  3. потом за 3 первых дня; 
  4. ...
  5. потом за весь период

 

Для каждого периода выполняем запрос, получаем объект РезультатЗапроса, дальше, работа идет уже именно с этим объектом.

ДатаОкончания = Период.ДатаОкончания;
ТекущаяДатаОкончания = КонецДня(Период.ДатаНачала);
Запрос = ПолучитьЗапрос();
Запрос.УстановитьПараметр("ДатаНачала", Период.ДатаНачала);

	
Пока ТекущаяДатаОкончания <= Период.ДатаОкончания Цикл
		
		Запрос.УстановитьПараметр("ДатаОкончания", ТекущаяДатаОкончания);
		
		РезультатЗапроса = Запрос.выполнить();
		стр = Замеры.Добавить();
		_Итоги_ДанныеВыборкой = ОбработатьДанныеВыборкой(РезультатЗапроса);
		_Итоги_ДанныеТЗ = ОбработатьДанныеТЗ(РезультатЗапроса);
		стр.КоличествоЗаписей = _Итоги_ДанныеВыборкой.КоличествоЗаписей;
		стр.ВремяДляВыборки = _Итоги_ДанныеВыборкой.Время;
		стр.ВремяДляТЗ = _Итоги_ДанныеТЗ.Время;
		стр.Коэффициент = стр.ВремяДляТЗ/стр.ВремяДляВыборки;
		
		
		ТекущаяДатаОкончания = КонецДня(ТекущаяДатаОкончания + 60*60*24);
КонецЦикла;

 

В данном контексте, время выполнения запроса нам не важно, нам важен этап дальнейшей обработки: через выборку или через таблицу значений.

Функция ОбработатьДанныеВыборкой(Результат) 
	
	КоличествоЗаписей = 0;
	Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Выборка = Результат.Выбрать();
	Пока выборка.следующий() Цикл
		
		КоличествоЗаписей = КоличествоЗаписей + 1;
	КонецЦикла;
	Конец = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	Возврат Новый структура("Время, КоличествоЗаписей", Конец-Начало, КоличествоЗаписей);
	
КонецФункции

Функция ОбработатьДанныеТЗ(Результат) 
	
	КоличествоЗаписей = 0;
	Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
	тз = Результат.Выгрузить();
	для каждого стр из тз Цикл
		
		КоличествоЗаписей = КоличествоЗаписей + 1;
	КонецЦикла;
	Конец = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	Возврат Новый структура("Время, КоличествоЗаписей", Конец-Начало, КоличествоЗаписей);
	
КонецФункции

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

_Итоги_ДанныеВыборкой = ОбработатьДанныеВыборкой(РезультатЗапроса);
_Итоги_ДанныеТЗ = ОбработатьДанныеТЗ(РезультатЗапроса);

стр.КоличествоЗаписей = _Итоги_ДанныеВыборкой.КоличествоЗаписей;
стр.ВремяДляВыборки = _Итоги_ДанныеВыборкой.Время;
стр.ВремяДляТЗ = _Итоги_ДанныеТЗ.Время;
стр.Коэффициент = стр.ВремяДляТЗ/стр.ВремяДляВыборки;

 

Обработка написана для толстого клиента (думаю, для выведения принципа это не критично), результаты произвольных замеров приведены ниже:

 

Результат 1

 

Результат 2

 

Вывод

Таблица значений при обработке результатов запроса - это удобно, но это - зло. Коэффициент падения производительности будет лежать в диапазоне от 2,5 (это в оптимистичном случае) и более. Если не используются преимущества индексирования, то лучше избегать использования таблиц значений.

Тестировал на платформе 1С:Предприятие 8.3 (8.3.13.1644) в режиме совместимости с 8.2.13.

Проверено на следующих конфигурациях и релизах:

  • Управление торговлей, редакция 10.3, релизы 10.3.45.4

См. также

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

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

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

13.03.2024    3664    spyke    28    

47

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

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

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

13.03.2024    5656    vasilev2015    19    

38

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

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

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

1 стартмани

15.02.2024    8568    170    ZAOSTG    74    

103

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

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

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

09.01.2024    6870    doom2good    49    

65

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

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

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

20.11.2023    9651    ivanov660    6    

76

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

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

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

15.11.2023    5461    a.doroshkevich    20    

72

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

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

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

11.10.2023    16768    skovpin_sa    14    

101
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. PowerBoy 3365 20.12.23 10:09 Сейчас в теме
Правильней было бы какое то значение из выборки и тз все таки считывать.
7. PowerBoy 3365 20.12.23 13:53 Сейчас в теме
(1) Оставьте только одно поле в запросе, повторите тест, сравните.
12. evgen7938 14 21.12.23 08:09 Сейчас в теме
(7) да, наверное, есть смысл. Возможно, стоит в таблицу значений добавить еще и индекс и сравнить разницу с учетом индексации таблицы.
2. RocKeR_13 1325 20.12.23 10:29 Сейчас в теме
Экзамен "1С:Специалист" по платформе "1С:Предприятие 8"
http://static.1c.ru/rus/partners/training/files/ATT83PL.rtf

Цитата из раздела с описаниями ошибок:

Выгрузка результата запроса в промежуточную таблицу (например, в таблицу значений) без необходимости - минус 1 балл


Здесь основная проблема заключается даже не столько в производительности, сколько в том, что выгрузка результата запроса сразу помещается в оперативную память. Особенно это чувствуется при использовании 32-битной платформы: при большой выборке данных работа просто будет прекращена из-за нехватки памяти. А вот при использовании выборки в случае превышения размера имеющейся памяти данные будут размещены во временных файлах и будут считываться при вызовах метода обхода выборки Следующий()

Источник: 1С:Предприятие 8. Система стандартов и методик разработки конфигураций
SagittariusA; ixijixi; +2 Ответить
4. starik-2005 3040 20.12.23 10:34 Сейчас в теме
(2)
при большой выборке
Хороший нюанс. Когда Вы обрабатывали действительно большую выборку в последний раз? Если с Вами такое случается регулярно, то у Вас проблемы с архитектурой.
5. RocKeR_13 1325 20.12.23 10:56 Сейчас в теме
(4) обычно большие объемы встречаются при различных интеграциях и обменах, когда нужно первоначально выгрузить большое количество данных. Есть импортеры с большими закупками маркируемых товаров или производители с той же маркировкой: в той или иной задаче опять же иногда приходится получать ощутимую выборку по товарам совместно с кодами маркировки.

Тем не менее, даже в рутинной работе все равно использую выборку из результата запроса. Сейчас даже не вспомню случая, когда нужно было прям вот в таблицу/дерево значений что-то выгружать.
3. starik-2005 3040 20.12.23 10:33 Сейчас в теме
Отличная статья! Но есть и нюансы. Например, получить значение из колонки таблицы значений примерно на 10% быстрее, чем из выборки. По крайней мере на моих данных. Несколько раз тестировал. Но если Вы таким образом считаете количество строк в запросе, то через выборку действительно быстрее.
NeLenin; PowerBoy; +2 Ответить
9. evgen7938 14 21.12.23 07:53 Сейчас в теме
(3) Можно еще использовать индексацию - это если данные приходится дергать хаотично, тогда быстрота индексов перевешивает замедление при создании таблицы, но это не точно )

Я к тому, что есть базовое утверждение - таблица значений создается дольше.

Какие преимущества дает этот объект и какие приемы можно использовать - мы пока не рассматриваем, просто, фиксируем факт.
6. ixijixi 1803 20.12.23 11:32 Сейчас в теме
таблица значений - это зло, но это удобно
На самом деле выборка не менее удобна, просто ТЗ визуально можно представить как цельный объект. Если абстрагироваться и представлять выборку в виде объекта, то и неудобства уйдут. По крайней мере, мне помогло.
11. evgen7938 14 21.12.23 08:05 Сейчас в теме
(6) в плане абстракции - да, можно попробовать. Здесь, углом встает вопрос индексирования некоторого объема данных.

Что если требуется быстро обработать набор данных не на стороне СУБД, а именно на сервере/клиенте? Что порекомендуете?
13. ixijixi 1803 21.12.23 08:39 Сейчас в теме
(11) Так от ситуации зависит: что за набор, что понимать под обработкой.
8. Xershi 1486 21.12.23 00:35 Сейчас в теме
Пару лет назад, может 5, видел статью.
Там анализировали обход коллекции через
РезультатЗапроса = Запрос.Выполнить()
И дальше обход результата.
И сразу выполнить и выбрать.
И расписывали какая команда какую даёт нагрузку. На железо.
Попробуйте тоже самое сделать?
10. evgen7938 14 21.12.23 08:00 Сейчас в теме
(8) Думаю, что нет. Наверное, это актуально при перегрузках "железа" большим количеством одновременных вычислительных операций.

У меня на горизонте пока нет таких "горячих" мест, но, конечно, если появятся риски "напороться" на такую особенность, то будем исследовать вопрос.
14. Xershi 1486 21.12.23 12:27 Сейчас в теме
(10) просто у вас такая красивая таблица, было бы здорово посмотреть на разницу.
15. NeLenin 13 29.12.23 16:55 Сейчас в теме
У меня при реализации данного алгоритма коэффициент получился около 2. А если еще некоторые вычисления добавить, то разница вполне может получиться не в пользу метода "Выбрать". Реализацию прикрепляю
Прикрепленные файлы:
Тест_СравнениеВыборкиИВыгрузки.zip
16. s22 19 04.01.24 15:33 Сейчас в теме
Это в обычных формах?
Код выполнялся в толстом клиенте?
Оставьте свое сообщение