Оптимизировать код

1. Lllypuk 26.09.24 00:55 Сейчас в теме
Здравствуйте! Помогите пожалуйста оптимизировать код.
Вижу только всё переписать заново в запросе и обойтись без вложенных запросов.

Спасибо!

ДопРасходыИмпортДокументы.Очистить();
	
	Если ПоступлениеТоваровИмпорт.ДопРасходыИмпорт.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ПоступлениеДопРасходов.Содержание КАК Содержание,
	|	ПоступлениеДопРасходов.Номенклатура КАК Номенклатура,
	|	СУММА(ПоступлениеДопРасходов.Сумма) КАК Сумма,
	|	МАКСИМУМ(ЗаказПоставщикуОтгруженный.Количество) КАК Количество,
	|	ПоступлениеДопРасходов.Валюта КАК Валюта,
	|	ПоступлениеДопРасходов.Курс КАК Курс,
	|	ПоступлениеДопРасходов.Контрагент КАК Контрагент,
	|	ПоступлениеДопРасходов.ДоговорВзаиморасчетов КАК Договор
	|ИЗ
	|	(ВЫБРАТЬ
	|		""ГТД: Таможенная пошлина"" КАК Содержание,
	|		ГТДИмпортТовары.Номенклатура КАК Номенклатура,
	|		ГТДИмпортТовары.Количество КАК Количество,
	|		ГТДИмпортТовары.СуммаПошлины КАК Сумма,
	|		ГТДИмпортТовары.Ссылка.ДоговорВзаиморасчетов.ВалютаВзаиморасчетов КАК Валюта,
	|		ГТДИмпортТовары.Ссылка.КурсВзаиморасчетов КАК Курс,
	|		ГТДИмпортТовары.Ссылка.Контрагент КАК Контрагент,
	|		ГТДИмпортТовары.Ссылка.ДоговорВзаиморасчетов КАК ДоговорВзаиморасчетов
	|	ИЗ
	|		Документ.ГТДИмпорт.Товары КАК ГТДИмпортТовары
	|	ГДЕ
	|		ГТДИмпортТовары.Ссылка.ДокументОснование = &Основание
	|		И ГТДИмпортТовары.Ссылка.Проведен
	|		И ГТДИмпортТовары.Номенклатура В(&МассивНоменклатуры)
	|	
	|	ОБЪЕДИНИТЬ ВСЕ
	|	
	|	ВЫБРАТЬ
	|		""ГТД: НДС"",
	|		ГТДИмпортТовары.Номенклатура,
	|		ГТДИмпортТовары.Количество,
	|		ГТДИмпортТовары.СуммаНДС,
	|		ГТДИмпортТовары.Ссылка.ДоговорВзаиморасчетов.ВалютаВзаиморасчетов,
	|		ГТДИмпортТовары.Ссылка.КурсВзаиморасчетов,
	|		ГТДИмпортТовары.Ссылка.Контрагент,
	|		ГТДИмпортТовары.Ссылка.ДоговорВзаиморасчетов
	|	ИЗ
	|		Документ.ГТДИмпорт.Товары КАК ГТДИмпортТовары
	|	ГДЕ
	|		ГТДИмпортТовары.Ссылка.ДокументОснование = &Основание
	|		И ГТДИмпортТовары.Ссылка.Проведен
	|		И ГТДИмпортТовары.Номенклатура В(&МассивНоменклатуры)
	|	
	|	ОБЪЕДИНИТЬ ВСЕ
	|	
	|	ВЫБРАТЬ
	|		""ГТД: Таможенный сбор"",
	|		ГТДИмпортТовары.Номенклатура,
	|		ГТДИмпортТовары.Количество,
	|		ГТДИмпортТовары.СуммаТаможня,
	|		ГТДИмпортТовары.Ссылка.ДоговорВзаиморасчетов.ВалютаВзаиморасчетов,
	|		ГТДИмпортТовары.Ссылка.КурсВзаиморасчетов,
	|		ГТДИмпортТовары.Ссылка.Контрагент,
	|		ГТДИмпортТовары.Ссылка.ДоговорВзаиморасчетов
	|	ИЗ
	|		Документ.ГТДИмпорт.Товары КАК ГТДИмпортТовары
	|	ГДЕ
	|		ГТДИмпортТовары.Ссылка.ДокументОснование = &Основание
	|		И ГТДИмпортТовары.Ссылка.Проведен
	|		И ГТДИмпортТовары.Номенклатура В(&МассивНоменклатуры)
	|	
	|	ОБЪЕДИНИТЬ ВСЕ
	|	
	|	ВЫБРАТЬ
	|		""ДР: "" + ПоступлениеДопРасходовИмпортТовары.Ссылка.Содержание,
	|		ПоступлениеДопРасходовИмпортТовары.Номенклатура,
	|		ПоступлениеДопРасходовИмпортТовары.Количество,
	|		ПоступлениеДопРасходовИмпортТовары.Сумма,
	|		ПоступлениеДопРасходовИмпортТовары.Ссылка.ВалютаДокумента,
	|		ПоступлениеДопРасходовИмпортТовары.Ссылка.КурсДокумента,
	|		ПоступлениеДопРасходовИмпортТовары.Ссылка.Контрагент,
	|		ПоступлениеДопРасходовИмпортТовары.Ссылка.ДоговорВзаиморасчетов
	|	ИЗ
	|		Документ.ПоступлениеДопРасходовИмпорт.Товары КАК ПоступлениеДопРасходовИмпортТовары
	|	ГДЕ
	|		ПоступлениеДопРасходовИмпортТовары.Ссылка.ДокументОснование = &Основание
	|		И ПоступлениеДопРасходовИмпортТовары.Ссылка.Проведен
	|		И ПоступлениеДопРасходовИмпортТовары.Номенклатура В(&МассивНоменклатуры)) КАК ПоступлениеДопРасходов
	|		ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
	|			ЗаказПоставщикуОтгруженныйТовары.Номенклатура КАК Номенклатура,
	|			СУММА(ЗаказПоставщикуОтгруженныйТовары.Количество) КАК Количество
	|		ИЗ
	|			Документ.ЗаказПоставщикуОтгруженный.Товары КАК ЗаказПоставщикуОтгруженныйТовары
	|		ГДЕ
	|			ЗаказПоставщикуОтгруженныйТовары.Ссылка = &Основание
	|		
	|		СГРУППИРОВАТЬ ПО
	|			ЗаказПоставщикуОтгруженныйТовары.Номенклатура) КАК ЗаказПоставщикуОтгруженный
	|		ПО ПоступлениеДопРасходов.Номенклатура = ЗаказПоставщикуОтгруженный.Номенклатура
	|
	|СГРУППИРОВАТЬ ПО
	|	ПоступлениеДопРасходов.Содержание,
	|	ПоступлениеДопРасходов.Номенклатура,
	|	ПоступлениеДопРасходов.Валюта,
	|	ПоступлениеДопРасходов.Курс,
	|	ПоступлениеДопРасходов.Контрагент,
	|	ПоступлениеДопРасходов.ДоговорВзаиморасчетов";
	Запрос.УстановитьПараметр("Основание", ПоступлениеТоваровИмпорт.ДокументОснование);
	Запрос.УстановитьПараметр("МассивНоменклатуры", ПоступлениеТоваровИмпорт.Товары.ВыгрузитьКолонку("Номенклатура"));
	
	ТЗ_Товары = ПоступлениеТоваровИмпорт.Товары.Выгрузить();
	ТЗ_Товары.Свернуть("Номенклатура", "Количество");
	
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		НоваяСтрокаТЧ = ДопРасходыИмпортДокументы.Добавить();
		НоваяСтрокаТЧ.Содержание = Выборка.Содержание;
		НоваяСтрокаТЧ.Контрагент = Выборка.Контрагент;
		НоваяСтрокаТЧ.Договор = Выборка.Договор;
		НоваяСтрокаТЧ.Валюта = Выборка.Валюта;
		НоваяСтрокаТЧ.Курс = Выборка.Курс;
		НоваяСтрокаТЧ.Часть = "ПОСЛЕ";
		
		нс = ТЗ_Товары.Найти(Выборка.Номенклатура, "Номенклатура");
		КолТовар = нс.Количество;
			
		Если КолТовар = Выборка.Количество Тогда
			НоваяСтрокаТЧ.Сумма = Выборка.Сумма;
		Иначе
			НоваяСтрокаТЧ.Сумма = Окр(Выборка.Сумма / Выборка.Количество * КолТовар, 2, 1);
		КонецЕсли;
		
		НоваяСтрокаТЧ.СуммаРуб	= НоваяСтрокаТЧ.Сумма * НоваяСтрокаТЧ.Курс;
		НоваяСтрокаТЧ.СуммаУпр	= _обПересчет(НоваяСтрокаТЧ.Сумма, НоваяСтрокаТЧ.Валюта, НоваяСтрокаТЧ.Курс, Константы.ВалютаУправленческогоУчетаКомпании.Получить(), ?(ЗначениеЗаполнено(ПоступлениеТоваровИмпорт.Дата), ПоступлениеТоваровИмпорт.Дата, ТекущаяДата()));
	КонецЦикла;
	ДопРасходыИмпортДокументы.Свернуть("Содержание,Контрагент,Договор,Валюта,Курс,Часть", "Сумма,СуммаРуб,СуммаУпр");
	ДопРасходыИмпортДокументы.Сортировать("Содержание,Часть");
Показать
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. nomad_irk 81 26.09.24 07:52 Сейчас в теме
(1) Замер времени выполнения запроса что показывает?
7. Lllypuk 26.09.24 16:13 Сейчас в теме
9. nomad_irk 81 26.09.24 16:28 Сейчас в теме
(7) а обслуживание базы выполняется вообще?
10. Lllypuk 26.09.24 16:30 Сейчас в теме
(9) Без понятия) обработка есть, даже проверить не могу, базу пока не видел
11. nomad_irk 81 26.09.24 16:37 Сейчас в теме
(10) вы бы выяснили сперва этот вопрос, а так же убедитесь в том, что все в порядке с железом, на котором работает SQL-сервер

Если все же база обслуживается, железо - адекватное, то проведите замеры каждого из запросов, чтобы понять, в каком именно месте нужно выполнять оптимизации.
3. user1936660 26.09.24 07:56 Сейчас в теме
(1)
оптимизировать код
На предмет чего - скорости выполнения, расхода памяти, минимизации сетевого трафика, простоты чтения и сопровождения... ?
8. Lllypuk 26.09.24 16:14 Сейчас в теме
(3) Скорости выполнения
4. user1936660 26.09.24 08:13 Сейчас в теме
(1)
...
Запрос.УстановитьПараметр("МассивНоменклатуры", ПоступлениеТоваровИмпорт.Товары.ВыгрузитьКолонку("Номенклатура"));
    
ТЗ_Товары = ПоступлениеТоваровИмпорт.Товары.Выгрузить();
ТЗ_Товары.Свернуть("Номенклатура", "Количество"); 
...
    нс = ТЗ_Товары.Найти(Выборка.Номенклатура, "Номенклатура");
...


Передай ПоступлениеТоваровИмпорт параметром в запрос и посчитай все внутри.
12. SlavaKron 26.09.24 17:02 Сейчас в теме
(1)
Вижу только всё переписать заново в запросе и обойтись без вложенных запросов.
Всё так, избавляйтесь от вложенных запросов, используйте временные таблицы.
Хотя, постойте, связи со вложенным запросом нет, значит дело не во вложенном запросе.
14. tolyan_ekb 80 27.09.24 10:14 Сейчас в теме
(1)
1.Надо сделать явное соединение с таблицей Документ.ГТДИмпорт и из нее получать данные Контрагент, Договор и т.д
2. Также сделать для Документ.ПоступлениеДопРасходовИмпорт
3. Не понятно зачем 3 раза выбирать одно и тоже и добавлять только колонку, можно получать данные из временной таблице и потому уже добавлять колонку
4. Соединение с вложенным запросом лучше убрать
15. Lllypuk 01.10.24 10:31 Сейчас в теме
(14) Не получается добавить 2 строки, все поля добавляются в единственную строку.
А в оригинале должно быть так:
Таможенная пошлина
НДС
Таможенный сбор

Получается выход один, использовать объединение таблиц:?
5. ImHunter 333 26.09.24 08:43 Сейчас в теме
(1) Мне вот не нравятся фрагменты запроса ... В(&МассивНоменклатуры).
Загрузить номенклатуры в ВТ и использовать внутреннее соединение.
Но в ВТ нужно загрузить уникальные значения номенклатур, без дублей.
Да и в вашем варианте тоже желательно это иметь в виду - в &МассивНоменклатуры установить уникальные значения.
6. user1936660 26.09.24 08:53 Сейчас в теме
(5)
Загрузить номенклатуры в ВТ и использовать внутреннее соединение.
А расскажи, пожалуйста - в чем будет отличие на уровне плана запроса и в чем ожидаемый выигрыш?
starik-2005; +1 Ответить
23. truba 01.10.24 11:45 Сейчас в теме
(6) технически вроде как (но это не точно) мы можем все свести к левым соединениям вместо объединить все и потом транспонировать таблицу уже при выдаче результата, а может вообще ее не надо транспонировать. Даст ли это выигрыш - хз, но...
13. Oldsad 27.09.24 04:22 Сейчас в теме
У вас в запросе трижды выбирается одна и таже таблица "Документ.ГТДИмпорт.Товары" даже если это действительно необходимо, то можно сначала ее подготовить, а потом утроить записи
16. truba 01.10.24 10:53 Сейчас в теме
к ТС:
1) 90 сек на запрос или на весь код?
2) Условия джойна в запросах прописать от большего к меньшему и от индексированного к не индексированному. Т.е. сначала .Проведен, Внутреннее соединение с ВТ_Номенклатура, потом по ссылке документов, условно в зависимости какая выборка меньше
3) Составные индексы тоже используй в последовательности от первого до последнего
17. Lllypuk 01.10.24 10:54 Сейчас в теме
18. truba 01.10.24 10:56 Сейчас в теме
(17) Давай таки определим основная нагрузка в запросе или далее в цикле. может там доки с 100500 строк номенклатуры и мы гоняем там поиск по номенклатуре без индекса те же 100500 раз, здесь количество важно.
и мы ничего не знаем об _обПересчет, может там собака зарыта.
19. Lllypuk 01.10.24 10:59 Сейчас в теме
(18) знал бы я, что там, может сюда бы не писал)) я просто делаю, отправляю, они проверяют)
20. user1880116 01.10.24 11:03 Сейчас в теме
(19)
я просто делаю, отправляю, они проверяют
Я смотрю, у тебя прямо работа мечты. Проверяют они, оптимизируют тебе на форуме...
22. Lllypuk 01.10.24 11:20 Сейчас в теме
(20) бывают базы к которым на пушечный выстрел не подпускают, отсюда сложность нету доков и данных для отладки
21. truba 01.10.24 11:06 Сейчас в теме
(19) Если мы _обПересчет не знаем и обязаны его выполнить, давай думать как его вес узнать при исполнении кода...

Вставь Сообщить("Текущее время шага 1 = " + ТекущаяДата());
И сообщить("Количество строк моей таблицы: " + Таблица.Количество());
во все осмысленные места в коде и попроси выслать тебе лог сообщений - станет много легче понимать что там происходит.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот