Блог 1С программиста (1С:Предприятие 8.3, конфигурация «Управление нашей фирмой»)

Статья: Запросы 1С: типичные ошибки

Запросы 1С: виртуальные таблицы, соединения и семь ошибок, которые тормозят базу

Почему условия нужно класть в параметры виртуальной таблицы, чем опасно обращение через точку к составному типу, зачем индексировать временные таблицы и как не писать запрос в цикле.

Конфигурация
Платформа 8.3
Платформа
8.3.24 и новее
Уровень
Средний
Опубликовано
22.07.2026
Время чтения
11 мин

Содержимое

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

Ошибка 1. Условие в ГДЕ вместо параметров виртуальной таблицы

Так писать нельзя:

ВЫБРАТЬ
	ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
	ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток
ИЗ
	РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
ГДЕ
	ТоварыНаСкладахОстатки.Склад = &Склад

Виртуальная таблица сначала посчитает остатки по всем складам, и только потом результат отфильтруется. Правильно — передать условие внутрь:

ВЫБРАТЬ
	Остатки.Номенклатура КАК Номенклатура,
	Остатки.КоличествоОстаток КАК Остаток
ИЗ
	РегистрНакопления.ТоварыНаСкладах.Остатки(
		&НаДату,
		Склад = &Склад
			И Номенклатура В (&СписокНоменклатуры)) КАК Остатки

Разница на большой базе — секунды против минут.

Ошибка 2. Обращение через точку к составному типу

Документ.Ссылка.Контрагент.НаименованиеПолное выглядит удобно, но каждая точка — это неявное левое соединение. Если поле составного типа (например, регистратор или значение субконто), платформа соединит запрос со всеми таблицами, которые входят в тип. Десяток соединений в одном поле — обычное дело.

Лечение — явное приведение типа:

ВЫБРАТЬ
	ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг).Контрагент КАК Контрагент
ИЗ
	РегистрНакопления.Продажи КАК Продажи

Ещё лучше — соединить с нужной таблицей явно и видеть, что происходит.

Ошибка 3. Соединение с виртуальной таблицей

Левое соединение с Остатки или СрезПоследних заставляет платформу материализовать всю виртуальную таблицу целиком. Правильный приём — сначала положить виртуальную таблицу во временную, проиндексировать и соединять уже с ней:

ВЫБРАТЬ
	Остатки.Номенклатура КАК Номенклатура,
	Остатки.КоличествоОстаток КАК Остаток
ПОМЕСТИТЬ ВТ_Остатки
ИЗ
	РегистрНакопления.ТоварыНаСкладах.Остатки(&НаДату, Склад = &Склад) КАК Остатки
ИНДЕКСИРОВАТЬ ПО
	Номенклатура
;

ВЫБРАТЬ
	Номенклатура.Ссылка КАК Номенклатура,
	ЕСТЬNULL(ВТ_Остатки.Остаток, 0) КАК Остаток
ИЗ
	Справочник.Номенклатура КАК Номенклатура
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Остатки КАК ВТ_Остатки
		ПО ВТ_Остатки.Номенклатура = Номенклатура.Ссылка
ГДЕ
	НЕ Номенклатура.ПометкаУдаления

Два правила отсюда: временные таблицы, участвующие в соединениях, индексируются по полям соединения, а результат левого соединения оборачивается в ЕСТЬNULL, иначе арифметика с NULL даст NULL.

Ошибка 4. Запрос в цикле

Классика, которая переживает поколения разработчиков:

// Так делать не нужно
Для Каждого Строка Из Документ.Товары Цикл
	Запрос.УстановитьПараметр("Номенклатура", Строка.Номенклатура);
	Результат = Запрос.Выполнить();
КонецЦикла;

Сто строк — сто обращений к серверу СУБД. Правильно: один запрос по всей табличной части, результат выгружается в таблицу значений или соответствие, а цикл идёт уже по нему.

Запрос.УстановитьПараметр("Номенклатура", Документ.Товары.ВыгрузитьКолонку("Номенклатура"));
ТаблицаЦен = Запрос.Выполнить().Выгрузить();

Ошибка 5. Отбор большим списком через В (…)

Список из нескольких тысяч элементов в В (&Список) работает плохо. Такие списки помещают во временную таблицу и соединяют с ней внутренним соединением — оптимизатор СУБД справляется с этим гораздо лучше.

Ошибка 6. ВЫБРАТЬ * и лишние поля

ВЫБРАТЬ * в 1С запрещён по синтаксису, но привычка «выберу все поля, вдруг пригодятся» жива. Каждое лишнее поле ссылочного типа — потенциальное соединение при выводе представления, лишний объём в памяти и лишний трафик между сервером и клиентом. Выбирайте только то, что реально используется.

Ошибка 7. ИТОГИ там, где нужны группировки

ИТОГИ ПО удобны для обхода результата по группировкам при печати. Но если нужны просто суммы, СГРУППИРОВАТЬ ПО дешевле: платформа не строит дерево.

Как проверять, а не гадать

  • Замер производительности в конфигураторе показывает, какие строки кода сколько занимают. Начинайте с него, а не с догадок.
  • Технологический журнал и события DBMSSQL дают текст запроса к СУБД и время выполнения.
  • План запроса на стороне СУБД показывает сканирование таблиц вместо использования индексов.
  • Тестируйте на объёме, близком к рабочему: на базе из ста документов ошибки не видно совсем.

Практический ориентир: если отчёт строится дольше десяти секунд, дело почти всегда в тексте запроса, а не в железе. Перепишите запрос по пунктам выше, прежде чем просить бюджет на новый сервер.