Advanced query optimization patterns beyond the basic rules.
When to use
- Complex multi-step data processing
- Optimizing JOINs and subqueries
- Working with DCS reports
- Processing large volumes of data
Temporary tables
JOIN vs Subquery
// ПРАВИЛЬНО: JOIN (обычно быстрее)
"ВЫБРАТЬ
| Заказы.Ссылка, Контрагенты.ИНН
|ИЗ Документ.ЗаказКлиента КАК Заказы
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
| ПО Заказы.Контрагент = Контрагенты.Ссылка"
// ПЛОХО: Подзапрос в SELECT (N+1)
"ВЫБРАТЬ
| Заказы.Ссылка,
| (ВЫБРАТЬ К.ИНН ИЗ Справочник.Контрагенты КАК К
| ГДЕ К.Ссылка = Заказы.Контрагент) КАК ИНН
|ИЗ Документ.ЗаказКлиента КАК Заказы"
Never JOIN with subqueries — use temporary tables
// ПЛОХО: JOIN с подзапросом
"... ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ ... СГРУППИРОВАТЬ ПО ...) КАК Итоги ..."
// ПРАВИЛЬНО: Временная таблица + JOIN
"ВЫБРАТЬ ... ПОМЕСТИТЬ ВТИтоги ... ИНДЕКСИРОВАТЬ ПО ...;
ВЫБРАТЬ ... ИЗ ... ЛЕВОЕ СОЕДИНЕНИЕ ВТИтоги ..."
Virtual table parameters
// ПРАВИЛЬНО: Фильтр В ПАРАМЕТРАХ виртуальной таблицы
"ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(
| &Дата, Номенклатура В (&Список)) КАК Остатки"
// ПЛОХО: Виртуальная таблица + ГДЕ
"ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата) КАК Остатки
|ГДЕ Остатки.Номенклатура В (&Список)"
Composite types — CAST
// ПЛОХО: Разыменование составного типа (запрос по ВСЕМ типам)
"ВЫБРАТЬ ТоварыНаСкладах.Регистратор.Дата"
// ПРАВИЛЬНО: ВЫРАЗИТЬ к конкретному типу
"ВЫБРАТЬ ВЫРАЗИТЬ(ТоварыНаСкладах.Регистратор
| КАК Документ.ПоступлениеТоваровУслуг).Дата"
PRESENTATION for display
// ПЛОХО: Доп. JOIN через точку
"ВЫБРАТЬ ТоварыНаСкладах.Склад.Наименование"
// ПРАВИЛЬНО: Без доп. JOIN
"ВЫБРАТЬ ПРЕДСТАВЛЕНИЕ(ТоварыНаСкладах.Склад) КАК Склад"
OR in WHERE → UNION ALL
// ПЛОХО: ИЛИ блокирует индексы
"ГДЕ Товары.Артикул = &Артикул ИЛИ Товары.Код = &Код"
// ПРАВИЛЬНО: Два запроса с ОБЪЕДИНИТЬ ВСЕ
"ВЫБРАТЬ ... ГДЕ Товары.Артикул = &Артикул
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ... ГДЕ Товары.Код = &Код"
UNION vs UNION ALL
Always ОБЪЕДИНИТЬ ВСЕ if duplicates do not need to be removed (faster — no grouping).
Virtual tables — first into a temporary table
// ПРАВИЛЬНО: Сначала извлечь, потом JOIN
"ВЫБРАТЬ ... ПОМЕСТИТЬ ВТОстатки
|ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата,) ИНДЕКСИРОВАТЬ ПО Номенклатура;
|ВЫБРАТЬ ... ИЗ Справочник.Номенклатура ЛЕВОЕ СОЕДИНЕНИЕ ВТОстатки ..."
Indexes
- The index must contain all fields of the condition
- Fields must be at the beginning of the index
- Fields must be consecutive (without gaps)
ИНДЕКСИРОВАТЬ ПОfor temporary tables in JOINs
Reference: ITS standards for query optimization