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

Tomash

Active Member
16.01.2013
40
0
#1
здравствуйте

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

Код:
		ТзПроданоПерУр=СоздатьОбъект("ТаблицаЗначений");
ТзПроданоПерУр.Загрузить(ТзПродано);
ТзПроданоПерУр.ВыбратьСтроки();
Пока ТзПроданоПерУр.ПолучитьСтроку()=1 Цикл
Пока ТзПроданоПерУр.Товар.Уровень()>1 Цикл
ТзПроданоПерУр.Товар=ТзПроданоПерУр.Товар.Родитель;
КонецЦикла;
КонецЦикла;
всё работает нормально, но по замеру в отладчике именно расчет родителя первого уровня для 10-12к товаров занимает 80% времени формирования отчета

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

Tomash

Active Member
16.01.2013
40
0
#2
опытным путем установил, что:

Код:
			Пока ПустоеЗначение(ТзПроданоПерУр.ТОвар.Родитель)=0 Цикл
работает в среднем на 30% быстрее, уже неплохо, но может можно что-то ещё выжать?
 

puh14

Well-Known Member
11.07.2008
1 412
0
#3
Те же яица , но вдруг быстреее
ПустРод = ПолучитьПустоеЗначение("Справочник.Номенклатура");
Если Стр.Родитель = пустРод Тогда
 

Glukman

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

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

vbs

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

Glukman

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

vbs

Well-Known Member
18.02.2007
1 708
3
#7
Решение не мое, автор если память не изменяет ака Рупор абсурда. на Мисте мелькало.

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


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

Tomash

Active Member
16.01.2013
40
0
#8
спасибо всем, проверил, все варианты рабочие, выдают один и тот же результат, но в данном конкретном отчете скорости на 15к товарах такие:

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

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