История одной оптимизации, давшей тысячекратный прирост производительности!

09.02.26

Разработка - Рефакторинг и качество кода

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

Эта история началась поставленной мне задачи переноса доработок функционала в документа Сверка взаиморасчетов 2.4 в документ Сверка взаиморасчетов 2.5.

Когда я увидел существующий код, мне сразу стало очевидно, что это вопиющие расточительство вычислительных ресурсов!

Мною был создан оптимизированный вариант. Замеры времени работы двух вариантов кода, на документе с табличной частью в пять тысяч строк, показали колоссальное различие в производительности:

Существующий код выполнился за 2006 секунд




Оптимизированный код выполнился за 2 секунды




Фантастика! Рост производительности в тысячу раз!

Ниже представлен существующий код:

&НаКлиенте
&После("ЗаполнитьПоОстаткамЗавершение")
Процедура ИНФ_ЗаполнитьПоОстаткамЗавершение(Результат, ДополнительныеПараметры) Экспорт

	ИНФ_ЗаполнитьПоОстаткамПосле(ЭтаФорма.Команды.ЗаполнитьПоОстаткам);

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

&НаКлиенте
Процедура ИНФ_ЗаполнитьПоОстаткамПосле(Команда)

	Для каждого Строка из Объект.ДетальныеЗаписиРасчеты Цикл
		Если  ТипЗНЧ(Строка.РасчетныйДокумент) = Тип("ДокументСсылка.ОтчетКомитенту") Тогда
			ВыбранноеЗначение = Строка.РасчетныйДокумент;
			НомерИМ = ПоискНомераЗаказаИМ(ВыбранноеЗначение);
			Если ЗначениеЗаполнено(НомерИМ) Тогда
				Строка.ОписаниеДокумента = "Заказ № " + НомерИМ.РезультатНомер + " от "+НомерИМ.РезультатДата;
			КонецЕсли;
		ИначеЕсли ТипЗНЧ(Строка.РасчетныйДокумент) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
			Строка.ОписаниеДокумента = Строка.ОписаниеДокумента + " (" + Строка(Строка.РасчетныйДокумент) + ")";
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

Функция ПоискНомераЗаказаИМ(ВыбранноеЗначение)
	ЗапросНомер = Новый Запрос;
	ЗапросНомер.УстановитьПараметр("Ссылка", ВыбранноеЗначение);
	ЗапросНомер.УстановитьПараметр("Свойство", ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "НомерЗаказаIM_42933da691f74ed6bbadc02702fb9ce9"));

	ЗапросНомер.Текст = "ВЫБРАТЬ
		|	ОтчетКомитентуДополнительныеРеквизиты.Значение КАК Значение
		|ИЗ
		|	Документ.ОтчетКомитенту.ДополнительныеРеквизиты КАК ОтчетКомитентуДополнительныеРеквизиты
		|ГДЕ
		|	ОтчетКомитентуДополнительныеРеквизиты.Ссылка = &Ссылка
		|	И ОтчетКомитентуДополнительныеРеквизиты.Свойство = &Свойство
		|";
	Выборка = ЗапросНомер.Выполнить().Выбрать();

	Пока Выборка.Следующий() Цикл
	    РезультатНомер = Выборка.Значение;
	КонецЦикла;

	ЗапросДата = Новый Запрос;
	ЗапросДата.УстановитьПараметр("Значение", РезультатНомер);
	ЗапросДата.УстановитьПараметр("Свойство", ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "НомерЗаказаIM_42933da691f74ed6bbadc02702fb9ce9"));

	ЗапросДата.Текст = "ВЫБРАТЬ
		|	ЗаказКлиентаДополнительныеРеквизиты.Значение КАК Значение,
		|	ЗаказКлиентаДополнительныеРеквизиты.Ссылка.Дата КАК Дата
		|ИЗ
		|	Документ.ЗаказКлиента.ДополнительныеРеквизиты КАК ЗаказКлиентаДополнительныеРеквизиты
		|ГДЕ
		|	ЗаказКлиентаДополнительныеРеквизиты.Свойство = &Свойство
		|	И ЗаказКлиентаДополнительныеРеквизиты.Значение = &Значение
		|";
	ВыборкаДата = ЗапросДата.Выполнить().Выбрать();

	Пока ВыборкаДата.Следующий() Цикл
	    РезультатДата = ВыборкаДата.Дата;
	КонецЦикла;

	РезультатНомер = СтрЗаменить(СокрЛ(СтрЗаменить(РезультатНомер,"0"," "))," ","0");
	РезультатДата = Формат(РезультатДата,"ДФ=dd.MM.yyyy");

	СтруктураТекст = Новый Структура;
	СтруктураТекст.Вставить("РезультатНомер",РезультатНомер);
    СтруктураТекст.Вставить("РезультатДата",РезультатДата);

	Возврат ?(СтруктураТекст=Неопределено,0,СтруктураТекст);
КонецФункции


Разберём недостатки этого кода:

Первый источник потерь  в процедуре "ИНФ_ЗаполнитьПоОстаткамПосле" реализован обход табличной части на клиенте с вызовом внутри тела цикла функции "ПоискНомераЗаказаИМ", выполняющейся на сервере.

Обращаю внимание, что перед объявлением функции "ПоискНомераЗаказаИМ" отсутствует какой-либо модификатор, это значит, что по умолчанию на сервер будет передаваться полный контекст формы.

При этом платформа 1С:

  • на стороне клиента, сериализует объект формы (со всеми реквизитами формы и объекта включая табличные части)
  • сериализованные данные передаются на сервер
  • на сервере, сериализованные данные десереализуются в объект формы
  • на сервере выполнятся вызванная функция 
  • сервер сериализует объект формы и возвращает его вместе с результатом функции на клиент
  • на стороне клиента, сериализованные данные десереализуются в объект формы

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

Второй источник потерь сама функция "ПоискНомераЗаказаИМ" в ней выполняются аж 4 запроса:

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

ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "НомерЗаказаIM_42933da691f74ed6bbadc02702fb9ce9")


Дополнительный реквизит можно было получить один раз перед телом цикла, поместить в переменную и далее использовать сохранённое в переменной значение.

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

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

&НаКлиенте
&После("ЗаполнитьПоОстаткамЗавершение")
Процедура ИНФ_ЗаполнитьПоОстаткамЗавершение(Результат, ДополнительныеПараметры) Экспорт

	ИНФ_КорректировкаТЧПриЗаполненииПоОстаткам();

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

&НаСервере
Процедура ИНФ_КорректировкаТЧПриЗаполненииПоОстаткам()

	Перем 	тзИсходныеДанные, КЧ, МассивТипов, сеДопустимыеТипы,
			Элем, Инд, КодТипа, ВГраница, Стр, НСтр, Свойство_НомерЗаказаIM,
			Запрос, РезультатЗапроса, Выборка1, Выборка2,
			НомерЗаказаIM, Инд_Пред;

	// НомерЗаказаIM
	Свойство_НомерЗаказаIM = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПолучитьСсылку(
			Новый УникальныйИдентификатор("8367e4de-3643-11ec-91f0-005056b343de")
		);

	КЧ = Новый КвалификаторыЧисла(10, 0);


	сеДопустимыеТипы = Новый Соответствие();

	сеДопустимыеТипы.Вставить(Тип("ДокументСсылка.ОтчетКомитенту"), 1);
	сеДопустимыеТипы.Вставить(Тип("ДокументСсылка.РеализацияТоваровУслуг"), 2);

	МассивТипов = Новый Массив();

	Для Каждого Элем Из сеДопустимыеТипы Цикл
		МассивТипов.Добавить(Элем.Ключ);
	КонецЦикла;

	тзИсходныеДанные = Новый ТаблицаЗначений();
	тзИсходныеДанные.Колонки.Добавить("Инд", Новый ОписаниеТипов("Число",,, КЧ));
	тзИсходныеДанные.Колонки.Добавить("РасчетныйДокумент", Новый ОписаниеТипов(МассивТипов));
	тзИсходныеДанные.Колонки.Добавить("КодТипа", Новый ОписаниеТипов("Число",,, КЧ));

	ВГраница = ЭтаФорма.Объект.ДетальныеЗаписиРасчеты.Количество() - 1;

	Для Инд = 0 По ВГраница Цикл

		Стр = ЭтаФорма.Объект.ДетальныеЗаписиРасчеты[Инд];

		КодТипа = сеДопустимыеТипы.Получить(ТипЗнч(Стр.РасчетныйДокумент));

		Если КодТипа = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		НСтр = тзИсходныеДанные.Добавить();
		НСтр.Инд = Инд;
		НСтр.РасчетныйДокумент = Стр.РасчетныйДокумент;
		НСтр.КодТипа = КодТипа;
	КонецЦикла;

	Запрос = Новый Запрос();
	Запрос.Текст =
"//0////////////////////////////////////////////////////////
|ВЫБРАТЬ
|	т.Инд,
|   т.РасчетныйДокумент,
|	т.КодТипа
|
|		ПОМЕСТИТЬ втИсходныеДанные
|
|ИЗ &тзИсходныеДанные КАК т
|
|ИНДЕКСИРОВАТЬ ПО
|	т.КодТипа
|
|;
|//1////////////////////////////////////////////////////////
|ВЫБРАТЬ
|	т.Инд,
|	ОтчетКомитентуДР.Значение КАК НомерЗаказаIM,
|   ЕСТЬNULL(ЗаказКлиента.Дата, ДАТАВРЕМЯ(1,1,1)) КАК ДатаЗаказа
|
|ИЗ втИсходныеДанные КАК т
|	ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ОтчетКомитенту.ДополнительныеРеквизиты КАК ОтчетКомитентуДР ПО
|			ОтчетКомитентуДР.Ссылка = т.РасчетныйДокумент
|		И	ОтчетКомитентуДР.Свойство = &Свойство_НомерЗаказаIM
|
|	ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента.ДополнительныеРеквизиты КАК ЗаказКлиентаДР ПО
|			ЗаказКлиентаДР.Свойство = &Свойство_НомерЗаказаIM
|		И	ЗаказКлиентаДР.Значение = ОтчетКомитентуДР.Значение
|
|	ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента КАК ЗаказКлиента ПО
|			НЕ ЗаказКлиентаДР.Ссылка ЕСТЬ NULL
|		И	ЗаказКлиента.Ссылка = ЗаказКлиентаДР.Ссылка
|
|ГДЕ
|		т.КодТипа = 1	// ОтчетКомитенту
|
|УПОРЯДОЧИТЬ ПО
|	т.Инд,
|	ЕСТЬNULL(ЗаказКлиента.Проведен, Ложь) УБЫВ,
|	ЕСТЬNULL(ЗаказКлиента.ПометкаУдаления, Ложь)
|;
|//2////////////////////////////////////////////////////////
|ВЫБРАТЬ
|	т.Инд,
|	ПРЕДСТАВЛЕНИЕ(ВЫРАЗИТЬ(т.РасчетныйДокумент КАК Документ.РеализацияТоваровУслуг)) КАК ПредставлениеДокумента
|
|ИЗ втИсходныеДанные КАК т
|ГДЕ
|		т.КодТипа = 2	// РеализацияТоваровУслуг
|";
	Запрос.УстановитьПараметр("тзИсходныеДанные", тзИсходныеДанные);
	Запрос.УстановитьПараметр("Свойство_НомерЗаказаIM", Свойство_НомерЗаказаIM);

	РезультатЗапроса = Запрос.ВыполнитьПакет();


	// ОтчетКомитенту

	Выборка1 = РезультатЗапроса[1].Выбрать();

	Пока Выборка1.Следующий() Цикл

		Если Выборка1.Инд = Инд_Пред Тогда
			Продолжить;
		КонецЕсли;

		Инд_Пред = Выборка1.Инд;

		Стр = ЭтаФорма.Объект.ДетальныеЗаписиРасчеты[Выборка1.Инд];

		НомерЗаказаIM = СтрЗаменить(
				СокрЛ(СтрЗаменить(Выборка1.НомерЗаказаIM, "0", " ")),
				" ", "0"
			);

		Стр.ОписаниеДокумента = СтрШаблон(
				"Заказ № %1 от %2",
		        НомерЗаказаIM,
				Формат(Выборка1.ДатаЗаказа, "ДФ=дд.ММ.гггг")
			);
	КонецЦикла;


	// РеализацияТоваровУслуг

	Выборка2 = РезультатЗапроса[2].Выбрать();

	Пока Выборка2.Следующий() Цикл

		Стр = ЭтаФорма.Объект.ДетальныеЗаписиРасчеты[Выборка2.Инд];

		Стр.ОписаниеДокумента = СтрШаблон(
				"%1 (%2)",
				Стр.ОписаниеДокумента,
				Выборка2.ПредставлениеДокумента
			);

	КонецЦикла;

КонецПроцедуры // ИНФ_КорректировкаТЧПриЗаполненииПоОстаткам


Вкратце пройдусь по применённым техническим решениям:

С клиента управление сразу передаётся на сервер и далее все манипуляции с табличной частью документа происходят на сервере.

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

	КЧ = Новый КвалификаторыЧисла(10, 0);


	сеДопустимыеТипы = Новый Соответствие();

	сеДопустимыеТипы.Вставить(Тип("ДокументСсылка.ОтчетКомитенту"), 1);
	сеДопустимыеТипы.Вставить(Тип("ДокументСсылка.РеализацияТоваровУслуг"), 2);

	МассивТипов = Новый Массив();

	Для Каждого Элем Из сеДопустимыеТипы Цикл
		МассивТипов.Добавить(Элем.Ключ);
	КонецЦикла;

	тзИсходныеДанные = Новый ТаблицаЗначений();
	тзИсходныеДанные.Колонки.Добавить("Инд", Новый ОписаниеТипов("Число",,, КЧ));
	тзИсходныеДанные.Колонки.Добавить("РасчетныйДокумент", Новый ОписаниеТипов(МассивТипов));
	тзИсходныеДанные.Колонки.Добавить("КодТипа", Новый ОписаниеТипов("Число",,, КЧ));


Заполнение таблицы значений выполняется через обход строк табличной части документа, путём обращения к ним через индекс. Это решение позволит при чтении данных из выборки сразу по индексу получать строку табличной части, к которой относятся данные выборки, то есть обойтись без поиска строк каждую итерацию цикла, по какому-либо набору полей.
 

	ВГраница = ЭтаФорма.Объект.ДетальныеЗаписиРасчеты.Количество() - 1;

	Для Инд = 0 По ВГраница Цикл

		Стр = ЭтаФорма.Объект.ДетальныеЗаписиРасчеты[Инд];

		КодТипа = сеДопустимыеТипы.Получить(ТипЗнч(Стр.РасчетныйДокумент));

		Если КодТипа = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		НСтр = тзИсходныеДанные.Добавить();
		НСтр.Инд = Инд;
		НСтр.РасчетныйДокумент = Стр.РасчетныйДокумент;
		НСтр.КодТипа = КодТипа;
	КонецЦикла;


Далее полученная таблица значений передаётся в качестве параметра в запрос, где к ней выполняются соединения таблиц базы, где находятся требующиеся данные.

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

	Выборка1 = РезультатЗапроса[1].Выбрать();

	Пока Выборка1.Следующий() Цикл

		Если Выборка1.Инд = Инд_Пред Тогда
			Продолжить;
		КонецЕсли;

		Инд_Пред = Выборка1.Инд;

		Стр = ЭтаФорма.Объект.ДетальныеЗаписиРасчеты[Выборка1.Инд];

		НомерЗаказаIM = СтрЗаменить(
				СокрЛ(СтрЗаменить(Выборка1.НомерЗаказаIM, "0", " ")),
				" ", "0"
			);

		Стр.ОписаниеДокумента = СтрШаблон(
				"Заказ № %1 от %2",
		        НомерЗаказаIM,
				Формат(Выборка1.ДатаЗаказа, "ДФ=дд.ММ.гггг")
			);
	КонецЦикла;


Код тестировался на платформе 8.3.27.1688, на конфигурации КА 2.5.22.134.

Вступайте в нашу телеграмм-группу Инфостарт

Оптимизация убираем запрос из цикла

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Нейросети Рефакторинг и качество кода Запросы Разработчик 1С 8.3 Абонемент ($m)

Нейросеть написала запрос или процедуру для вашей базы 1С, и непонятно, все ли имена в нём настоящие. Обработка компилирует текст без выполнения, сверяет его с метаданными этой базы и к каждой ошибке пишет настоящее имя, например ВНаличииОстаток вместо выдуманного КоличествоОстаток. Список ошибок с подсказками одной кнопкой копируется обратно в чат с моделью.

10 стартмани

02.11.2026    386    2    nedomolkov.ivan    3    

3

Рефакторинг и качество кода Разработчик 1С:Предприятие 8 Россия Бесплатно (free)

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

29.10.2026    399    YA_777378709    0    

4

Рефакторинг и качество кода Разработчик Бесплатно (free)

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

28.10.2026    509    Pavel791    0    

2

Рефакторинг и качество кода HighLoad оптимизация Системный администратор Разработчик Стажер 1С 8.3 Абонемент ($m)

Если к HTTP-сервису 1С обращаются сразу несколько программ, сколько запросов в секунду он успеет обработать? Я опубликовала простой HTTP-сервис на нашей "подопытной" конфигурации «Нано-УТ» (файловая база, Apache, без прав администратора) и нагрузила его скриптом на Python. Ответ: около 15-16 запросов в секунду, сколько бы клиентов ни обращалось одновременно. Запросы ждут своей очереди, и при 32 клиентах ответ приходит через 2 секунды вместо 64 мс. Заодно разобрала скрипт из первого варианта статьи: он «проверял» сервер, который отвечал по одному, и считал ошибки вместе с успешными ответами. В архиве исправленный скрипт, учебный сервер, HTTP-сервис для 1С и инструкция по запуску.

1 стартмани

23.10.2026    544    Ninel_S    3    

2

Рефакторинг и качество кода Разработчик 1С 8.3 Абонемент ($m)

Запустили Analyzer 1C 2.7.65 на промышленной конфигурации (596 модулей, 13 669 функций) и исследовали перегруженные функции (до 1887 строк), циклические зависимости и экран «Циклы» (кольцо из 64 модулей). Разобрали, почему популярные метрики (McCabe, связность) не представлены в продукте вендора, и составили пошаговый план разделения модуля. Привели проверенный платформой 8.3.27 пример до и после рефакторинга и выявили скрытую ловушку загрузки модулей с точкой в имени.

9 стартмани

19.10.2026    482    Ninel_S    2    

2

Рефакторинг и качество кода EDT СКД Разработчик 1С 8.3 1С 8.5 1С:Бухгалтерия 3.0 Бесплатно (free)

Одиннадцать граблей схем компоновки, которые не видно в конструкторе и не ловит EDT, на реальных отчетах БП КОРП. Формат числа задается в двух местах, и условное оформление варианта перебивает формат поля. Ресурс складывает штуки с часами, и помогает выражение «только когда единица одна». Ресурс пуст в детальных записях, параметр не появляется в шапке без userSettingID, valueListAllowed ломает границы периода, Остатки и СрезПоследних с параметром периода падают с «Несоответствием типов», title без xsi:type дает «Исключение XDTO» при загрузке. В конце код проверки схемы из файла до обновления базы, сводная таблица и чеклист.

16.10.2026    560    Konstmax13    2    

2

Инструментарий разработчика Нейросети Рефакторинг и качество кода EDT Разработчик 1С 8.3 1С 8.5 1С:Бухгалтерия 3.0 Бесплатно (free)

Как ИИ-агент (Claude Code) работает в живом EDT-проекте 1С:Бухгалтерии КОРП 3.0: из чего собрать стенд с MCP-сервером для EDT, как ставить задачи агенту, где он ломает проект и какие проверки это ловят. Реальные случаи: рукописные метаданные, ронявшие конфигуратор; четыре дня зависшего обновления из-за порядка блоков в Rights.rights; ошибки, которые EDT пропускает, а платформа нет; сплошная сверка вместо «вроде работает». В приложении шаблон CLAUDE.md, шаблон правила, чеклист перед обновлением базы и скрипты проверки ролей и схем СКД.

15.10.2026    3568    Konstmax13    11    

11

Рефакторинг и качество кода Тестирование QA Разработчик 1С 8.3 Абонемент ($m)

Инженерный анализ влияния (Impact Analysis) при изменении общего метода в 1С:Предприятии: почему штатный поиск ссылок скрывает 99% зависимостей и как обратный обход графа вызовов выявляет 370 скрытых потребителей на глубине 3 уровней. В статье — верификация сквозной цепочки обмена с маркетплейсом; в архиве-компаньоне — автономный BFS-анализатор на Python, слепки графа и план регрессионного тестирования.

1 стартмани

12.10.2026    343    Ninel_S    0    

2
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. user-z99999 77 09.02.26 14:40 Сейчас в теме
А учтена ситуация, когда в документ в табличную часть добавляется новая строка?
как там данные будут получены.

Вообще, если хотите сильно уменьшить, попробуйте вообще не считать на сервере,
если логика работы позволяет.
Только при нажатии на кнопку, один раз бежим на сервер и всё приносим. Пользователь сам определяет когда.
Чтобы для черновика не бегать.
2. paulwist 09.02.26 14:42 Сейчас в теме
ИНДЕКСИРОВАТЬ ПО
| т.КодТипа


1. Сколько записей в ВТ с КодТипа =1 и КодТипа =2 ??

2. Объясните, зачем индексируете по т.КодТипа, какой результат хотите получить?
9. Eugen-S 457 14.02.26 15:29 Сейчас в теме
(2) В теории отбор по индексированному полю работает быстрее, чем по неиндексированному.
В последующих запросах идёт отбор как раз по этому полю, поэтому я применил индексацию.
Обратная сторона индексации, что при наличии индексации на запись строки таблицы расходуется чуть больше времени.

А в общем, Ваш вопрос напоминает расхожий в интернете комикс-притчу, про отца, сына и их осла.
Если бы я не сделал индексацию, обязательно в комментариях появился бы тот, кто спросил бы почему я её не сделал.

Поэтому я решил, что лучше её сделать, чем не сделать.
VyacheslavShilov; +1 – Ответить
10. paulwist 16.02.26 08:51 Сейчас в теме
(9)
В последующих запросах идёт отбор как раз по этому полю, поэтому я применил индексацию.


Хмм, в запросах вижу, что отбор идёт по предикату КодТипа =1 и КодТипа =2, кстати по которому нет индекса (о его необходимости говорит ответ на вопрос 1. Сколько записей в ВТ с КодТипа =1 и КодТипа =2 ??
) и не вижу отбор по т.Инд.


(9)
А в общем, Ваш вопрос напоминает расхожий в интернете комикс-притчу, про отца, сына и их осла.
Если бы я не сделал индексацию, обязательно в комментариях появился бы тот, кто спросил бы почему я её не сделал.


Хех, так вы не ответили на вопрос, какой результат хотите получить?
Ответив на него и глядя на план запроса можно говорить нужен индекс или нет.

Можете привести план запросов??
3. sapervodichka 7710 09.02.26 15:15 Сейчас в теме
Вообще я не склонен ругать разработчика за первоначальный неоптимальный код. Сначала ведь надо в принципе написать какое-то рабочее решение (там и с ТЗ могут быть проблемы - непонятно что в итоге сделать, поэтому делают максимально просто и с возможностью быстро поправить, и делать могут в демке на 1-5 записях где проблема не видна). А вот далее на реальных данных можно и нужно решение оптимизировать, но вот только на оптимизацию чаше всего времени или денег не дают, что очень жаль. А она нужна.
Автору, чашечка уважения. Приятно читать задачи по оптимизации и складывать себе на подкорку.
SemandCheb; +1 – Ответить
4. paulwist 10.02.26 08:26 Сейчас в теме
(3)
А вот далее на реальных данных можно и нужно решение оптимизировать,


Дык у ТСа "реальные" данные - 2006 сек запрос отрабатывал, если принять "пальцем в небо" что 2 сек обрабатывается одна запись, то получается 1000 записей.

Что фактически сделал ТС, он "заменил" 1000 транзакций на одну и получил ожидаемое ускорение.
5. sapervodichka 7710 10.02.26 08:33 Сейчас в теме
(4) я писал о том, что написание кода по ТЗ и его оптимизация - это две разные задачи, которые делают разные люди в разное время. То что там 2006, 1000, ускорение и т.д. я прочитал не слепой
6. paulwist 10.02.26 10:19 Сейчас в теме
(5)
я писал о том, что написание кода по ТЗ и его оптимизация - это две разные задачи


Тут возражений нет :) +100500
sapervodichka; +1 – Ответить
7. starik-2005 3309 10.02.26 10:43 Сейчас в теме
Лет шесть назад оптимизировал загрузку недействительных паспортов. Начальное время вставки в таблицу из двух полей с индексами в 1С было 8 часов, итого на С формирование битовой маски работало за полторы минуты (из них 95% времени - это распаковка 1G+ gz-файла). Т.е. в 320 раз, если с временем распаковки. Если же считать только время загрузки, то в стопиццот раз.
VyacheslavShilov; +1 – Ответить
8. axelerleo 327 13.02.26 23:50 Сейчас в теме
Хороший пример своевременной оптимизации. Как правило, практически любая разработка проходит стадии от "сделай хоть как-то" до "сделай чтоб быстро". Богачев говорит, что преждевременная оптимизация не имеет особого смысла, и омтимизировать надо то, что реально тормозит, и тогда, когда реально тормозит. А для выявления этого есть нагрузочные тесты. Вот тогда то весь код и всплывает :)
Eugen-S; VyacheslavShilov; +2 – Ответить
Для отправки сообщения требуется регистрация/авторизация