База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как оптимизировать запрос получения сумм и курсов валют по счетам?
- В этой теме 1 ответ, 2 участника, последнее обновление 3 дня, 21 час назад сделано
Odin — Одинэсник.
-
АвторСообщения
-
-
30 апреля 2026 в 20:08 #36911
ВЫБРАТЬ
СчетНаОплатуПокупателю.Ссылка КАК Ссылка,
СУММА(СчетНаОплатуПокупателюУслуги.Сумма) КАК Сумма,
СчетНаОплатуПокупателю.Дата КАК Дата
ПОМЕСТИТЬ ВТ_Док
ИЗ
Документ.СчетНаОплатуПокупателю.Услуги КАК СчетНаОплатуПокупателюУслуги
ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю
ПО СчетНаОплатуПокупателюУслуги.Ссылка = СчетНаОплатуПокупателю.Ссылка
ГДЕ
СчетНаОплатуПокупателю.Ссылка В(&Ссылка)СГРУППИРОВАТЬ ПО
СчетНаОплатуПокупателю.Ссылка,
СчетНаОплатуПокупателю.Дата
;////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВложенныйЗапрос.Ссылка КАК Ссылка,
ВложенныйЗапрос.Сумма КАК Сумма,
КурсыВалют.Курс КАК Курс,
ВложенныйЗапрос.Период КАК Период
ИЗ
(ВЫБРАТЬ
МАКСИМУМ(КурсыВалют.Период) КАК Период,
ВТ_Док.Ссылка КАК Ссылка,
ВТ_Док.Сумма КАК Сумма
ИЗ
РегистрСведений.КурсыВалют КАК КурсыВалют
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Док КАК ВТ_Док
ПО КурсыВалют.Период <= ВТ_Док.ДатаСГРУППИРОВАТЬ ПО
ВТ_Док.Ссылка,
ВТ_Док.Сумма) КАК ВложенныйЗапрос
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
ПО ВложенныйЗапрос.Период = КурсыВалют.Период
ГДЕ
КурсыВалют.Валюта = &Валюта оптимален ли этот запрос -
30 апреля 2026 в 20:08 #36912
Запрос в целом решает задачу — для каждого документа из списка (&Ссылка) получает сумму услуг и дату, затем для каждой даты находит курс валюты по валюте &Валюта, ближайший к дате (максимальный период курса, не превышающий дату документа).
Но есть несколько моментов, которые могут повлиять на производительность и читаемость:
1. В первом запросе:
— Используется ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетНаОплатуПокупателю с табличной частью по ссылке. Обычно табличная часть всегда связана с документом, поэтому можно заменить на ВНУТРЕННЕЕ СОЕДИНЕНИЕ — это ускорит запрос.
— Фильтр по СчетНаОплатуПокупателю.Ссылка В(&Ссылка) — если &Ссылка большой список, убедитесь, что параметр передается корректно и индекс по ссылке есть.2. Во втором запросе:
— Вложенный запрос с соединением КурсыВалют.Период <= ВТ_Док.Дата и группировкой по ВТ_Док.Ссылка, ВТ_Док.Сумма — это классический способ найти последний курс на дату.
— Однако, если в КурсыВалют много записей, и периодов много, то соединение может быть тяжелым.
— Можно оптимизировать, если в КурсыВалют есть индекс по Валюта и Период, и если период ограничен по диапазону.
— Также можно рассмотреть вариант с использованием подзапроса для выбора максимального периода для каждой даты документа, чтобы избежать большого соединения.3. В целом, если количество документов и курсов не очень большое — запрос будет работать нормально.
4. Если база большая, рекомендую:
— Ограничить период выборки курсов (например, по диапазону дат документов).
— Проверить индексы по полям КурсыВалют.Валюта и КурсыВалют.Период.
— Рассмотреть вариант предварительного кэширования курсов в таблице значений.Пример оптимизации подзапроса для выбора максимального периода:
|ВЫБРАТЬ
| ВТ_Док.Ссылка,
| ВТ_Док.Сумма,
| (ВЫБРАТЬ МАКСИМУМ(КурсыВалют.Период)
| ИЗ РегистрСведений.КурсыВалют КАК КурсыВалют
| ГДЕ КурсыВалют.Валюта = &Валюта
| И КурсыВалют.Период <= ВТ_Док.Дата) КАК Период
|ИЗ
| ВТ_Док КАК ВТ_ДокДалее соединять с КурсыВалют по Период и Валюта.
Итог: запрос рабочий, но для больших объемов данных стоит проверить индексы и, возможно, ограничить периоды, а также заменить ЛЕВОЕ СОЕДИНЕНИЕ на ВНУТРЕННЕЕ в первом запросе.
-
-
АвторСообщения
- Для ответа в этой теме необходимо авторизоваться.