--- name: 1c-query-opt description: "Продвинутые паттерны оптимизации запросов 1С: временные таблицы, JOIN vs подзапросы, параметры виртуальных таблиц, СКД, индексы. Используй для сложных запросов." allowed-tools: - Read - Grep - Glob --- # /1c-query-opt — Оптимизация запросов 1С Продвинутые паттерны оптимизации запросов за пределами базовых правил. ## Когда использовать - Сложная многошаговая обработка данных - Оптимизация JOIN и подзапросов - Работа с отчётами СКД - Обработка больших объёмов данных ## Временные таблицы ### JOIN vs Подзапрос ```bsl // ПРАВИЛЬНО: JOIN (обычно быстрее) "ВЫБРАТЬ | Заказы.Ссылка, Контрагенты.ИНН |ИЗ Документ.ЗаказКлиента КАК Заказы | ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты | ПО Заказы.Контрагент = Контрагенты.Ссылка" // ПЛОХО: Подзапрос в SELECT (N+1) "ВЫБРАТЬ | Заказы.Ссылка, | (ВЫБРАТЬ К.ИНН ИЗ Справочник.Контрагенты КАК К | ГДЕ К.Ссылка = Заказы.Контрагент) КАК ИНН |ИЗ Документ.ЗаказКлиента КАК Заказы" ``` ### Никогда не JOIN с подзапросами — используй временные таблицы ```bsl // ПЛОХО: JOIN с подзапросом "... ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ ... СГРУППИРОВАТЬ ПО ...) КАК Итоги ..." // ПРАВИЛЬНО: Временная таблица + JOIN "ВЫБРАТЬ ... ПОМЕСТИТЬ ВТИтоги ... ИНДЕКСИРОВАТЬ ПО ...; ВЫБРАТЬ ... ИЗ ... ЛЕВОЕ СОЕДИНЕНИЕ ВТИтоги ..." ``` ## Параметры виртуальных таблиц ```bsl // ПРАВИЛЬНО: Фильтр В ПАРАМЕТРАХ виртуальной таблицы "ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки( | &Дата, Номенклатура В (&Список)) КАК Остатки" // ПЛОХО: Виртуальная таблица + ГДЕ "ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата) КАК Остатки |ГДЕ Остатки.Номенклатура В (&Список)" ``` ## Составные типы — ВЫРАЗИТЬ ```bsl // ПЛОХО: Разыменование составного типа (запрос по ВСЕМ типам) "ВЫБРАТЬ ТоварыНаСкладах.Регистратор.Дата" // ПРАВИЛЬНО: ВЫРАЗИТЬ к конкретному типу "ВЫБРАТЬ ВЫРАЗИТЬ(ТоварыНаСкладах.Регистратор | КАК Документ.ПоступлениеТоваровУслуг).Дата" ``` ## ПРЕДСТАВЛЕНИЕ для отображения ```bsl // ПЛОХО: Доп. JOIN через точку "ВЫБРАТЬ ТоварыНаСкладах.Склад.Наименование" // ПРАВИЛЬНО: Без доп. JOIN "ВЫБРАТЬ ПРЕДСТАВЛЕНИЕ(ТоварыНаСкладах.Склад) КАК Склад" ``` ## ИЛИ в ГДЕ → ОБЪЕДИНИТЬ ВСЕ ```bsl // ПЛОХО: ИЛИ блокирует индексы "ГДЕ Товары.Артикул = &Артикул ИЛИ Товары.Код = &Код" // ПРАВИЛЬНО: Два запроса с ОБЪЕДИНИТЬ ВСЕ "ВЫБРАТЬ ... ГДЕ Товары.Артикул = &Артикул |ОБЪЕДИНИТЬ ВСЕ |ВЫБРАТЬ ... ГДЕ Товары.Код = &Код" ``` ## ОБЪЕДИНИТЬ vs ОБЪЕДИНИТЬ ВСЕ Всегда `ОБЪЕДИНИТЬ ВСЕ` если не нужно удалять дубликаты (быстрее — нет группировки). ## Виртуальные таблицы — сначала во временную ```bsl // ПРАВИЛЬНО: Сначала извлечь, потом JOIN "ВЫБРАТЬ ... ПОМЕСТИТЬ ВТОстатки |ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата,) ИНДЕКСИРОВАТЬ ПО Номенклатура; |ВЫБРАТЬ ... ИЗ Справочник.Номенклатура ЛЕВОЕ СОЕДИНЕНИЕ ВТОстатки ..." ``` ## Индексы 1. Индекс должен содержать **все поля** условия 2. Поля должны быть **в начале** индекса 3. Поля должны быть **последовательными** (без пропусков) 4. `ИНДЕКСИРОВАТЬ ПО` для временных таблиц при JOIN --- **Справка**: [Стандарты ITS по оптимизации запросов](https://its.1c.ru/db/v8std/browse/13/-1/26/28)