• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

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

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Быстрый Поиск Родителя Первого Уровня

  • Автор темы Tomash
  • Дата начала
T

Tomash

здравствуйте

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

Код:
		ТзПроданоПерУр=СоздатьОбъект("ТаблицаЗначений");
ТзПроданоПерУр.Загрузить(ТзПродано);
ТзПроданоПерУр.ВыбратьСтроки();
Пока ТзПроданоПерУр.ПолучитьСтроку()=1 Цикл
Пока ТзПроданоПерУр.Товар.Уровень()>1 Цикл
ТзПроданоПерУр.Товар=ТзПроданоПерУр.Товар.Родитель;
КонецЦикла;
КонецЦикла;

всё работает нормально, но по замеру в отладчике именно расчет родителя первого уровня для 10-12к товаров занимает 80% времени формирования отчета

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

Tomash

опытным путем установил, что:

Код:
			Пока ПустоеЗначение(ТзПроданоПерУр.ТОвар.Родитель)=0 Цикл

работает в среднем на 30% быстрее, уже неплохо, но может можно что-то ещё выжать?
 
P

puh14

Те же яица , но вдруг быстреее
ПустРод = ПолучитьПустоеЗначение("Справочник.Номенклатура");
Если Стр.Родитель = пустРод Тогда
 
G

Glukman

ТзПроданоПерУр=СоздатьОбъект("ТаблицаЗначений");
ТзПроданоПерУр.Загрузить(ТзПродано);
ТзПроданоПерУр.ВыбратьСтроки();
Пока ТзПроданоПерУр.ПолучитьСтроку()=1 Цикл
Спр = ТзПроданоПерУр.Товар;
ВерхнийРодитель=ЗначениеИзСтрокиВнутр(Шаблон("[ЗначениеВСтрокуВнутр(Спр"+СтрЗаменить(Формат("","С"+(Спр.Уровень()-1))," ",".Родитель")+")]"));
ТзПроданоПерУр.Товар = ВерхнийРодитель;
КонецЦикла;

Попробуйте так.
Суть убыстрения - будет один проход по циклу без излишнего перебора.
 
V

vbs

Хороший способ предложил Glukman.
Но я тоже решил развлечься и проверил свой метод :
Код:
ТзПроданоПерУр=СоздатьОбъект("ТаблицаЗначений");
ТзПроданоПерУр.Загрузить(ТзПродано);
ТзПроданоПерУр.ВыбратьСтроки();
NN = CreateObject("Reference.Номенклатура"); // возможно, название справочника другое
Пока ТзПроданоПерУр.ПолучитьСтроку()=1 Цикл
Спр = ТзПроданоПерУр.Товар.;
Slash = Find(Спр.FullCode(),"/");	
Code = Left(Спр.FullCode(),Slash-1);
NN.FindByCode(Code);
ТзПроданоПерУр.Товар = NN.CurrentItem(); //ВерхнийРодитель;
КонецЦикла;
На выборке из 30 тыс. позиций у меня работает в 3 раза быстрее.
Видимо, преобразование во внутреннее представление и обратно работает все же медленнее
 
G

Glukman

Хороший способ предложил Glukman.
Но я тоже решил развлечься и проверил свой метод :
Код:
ТзПроданоПерУр=СоздатьОбъект("ТаблицаЗначений");
ТзПроданоПерУр.Загрузить(ТзПродано);
ТзПроданоПерУр.ВыбратьСтроки();
NN = CreateObject("Reference.Номенклатура"); // возможно, название справочника другое
Пока ТзПроданоПерУр.ПолучитьСтроку()=1 Цикл
Спр = ТзПроданоПерУр.Товар.;
Slash = Find(Спр.FullCode(),"/");	
Code = Left(Спр.FullCode(),Slash-1);
NN.FindByCode(Code);
ТзПроданоПерУр.Товар = NN.CurrentItem(); //ВерхнийРодитель;
КонецЦикла;
На выборке из 30 тыс. позиций у меня работает в 3 раза быстрее.
Видимо, преобразование во внутреннее представление и обратно работает все же медленнее

А вот про полный код забыл. Решение не мое, автор если память не изменяет ака Рупор абсурда. на Мисте мелькало.
 
V

vbs

Решение не мое, автор если память не изменяет ака Рупор абсурда. на Мисте мелькало.

Я имею обыкновение проверять чужие предложения, если понимаю, как надо :blush:
Часто интересные идеи мелькают - так я их в свою библиотеку...


Еще чуточку быстрее должно сработать так :
Спр = ТзПроданоПерУр.Товар.FullCode();
Slash = Find(Спр,"/");
Code = Left(Спр,Slash-1);
 
T

Tomash

спасибо всем, проверил, все варианты рабочие, выдают один и тот же результат, но в данном конкретном отчете скорости на 15к товарах такие:

1. Оригинал - 90,33 сек
2. Условие цикла - ПустоеЗначение() - 67,69 сек
3. Вариант от vbs - 49,15 сек
4. Вариант от Glukman - 45,74 сек

не славы ради, но спортивного интереса для ;)
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!