Как устранить ошибку «Недостаточно памяти для получения результата запроса к базе данных» в 1С:Предприятие?

Системный администратор 1С v8.3 (Обычные формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

При работе в конфигурациях на платформе 1С:Предприятие 8.3 пользователи нередко сталкиваются с аварийным завершением операций и ошибкой: Ошибка выполнения запроса: Недостаточно памяти для получения результата запроса к базе данных. Чаще всего сбой проявляется в процессе подбора номенклатуры, при проведении тяжелых документов или формировании нетиповых отчетов. Разберем детально физику возникновения этой проблемы, проанализируем распределение ресурсов между сервером СУБД и сервером 1С, а также пошагово выполним системные и программные настройки для полного устранения сбоя.

Причины возникновения ошибки нехватки памяти

Для эффективной локализации проблемы выясним, на каком именно уровне инфраструктуры происходит исчерпание памяти. В архитектуре клиент-серверной работы 1С задействованы три ключевых звена: клиентское приложение (толстый или тонкий клиент), кластер серверов 1С (процессы rphost, rmngr) и сервер реляционной СУБД (например, Microsoft SQL Server или PostgreSQL).

Рассмотрим основные факторы, приводящие к ошибке:

  1. Архитектурный лимит 32-битного клиентского приложения: Если база данных работает в режиме обычного приложения (толстый клиент, характерный для конфигураций «Бухгалтерия предприятия 2.0», «Управление торговлей 10.3», «Управление производственным предприятием 1.3»), конструкция Запрос.Выполнить() выполняется непосредственно в адресном пространстве процесса 1cv8.exe на компьютере пользователя. Для 32-битных процессов Windows накладывает жесткое ограничение в 2 ГБ виртуального адресного пространства. При наличии фрагментации оперативной памяти сбой возникает уже при выделении 1.2–1.6 ГБ, даже если физически на рабочей станции установлено 8 или 16 ГБ ОЗУ.
  2. Неконтролируемое потребление памяти MS SQL Server: По умолчанию СУБД Microsoft SQL Server динамически занимает всю доступную физическую оперативную память сервера под собственный буферный пул (Buffer Pool). Если SQL Server и сервер 1С установлены на одной машине с 32 ГБ ОЗУ, СУБД может занять 28–30 ГБ, оставив процессам rphost и операционной системе считаные мегабайты, что провоцирует системный дефицит ресурсов.
  3. Неоптимальные запросы без фильтрации данных: В обработках подбора номенклатуры нередко выполняется запрос к виртуальным таблицам остатков и цен без передачи параметров отбора (по номенклатурной группе, складу или наличию ненулевого остатка). При номенклатурном справочнике в 30 000–100 000 позиций результат выборки превращается в массив из сотен тысяч строк, который СУБД передает в клиентское приложение в виде огромной таблицы значений.
  4. Некорректная оценка кардинальности запросов в MS SQL Server 2014/2016/2017: После миграции базы на новые версии SQL Server новый механизм оценки кардинальности (Cardinality Estimator) может генерировать неэффективные планы запросов для структур 1С, вызывая раздувание промежуточных результатов в базе tempdb и чрезмерный расход памяти.

Шаг 1. Переход на 64-битный клиент 1С:Предприятие

Если сбой происходит на рабочих местах пользователей в конфигурациях с обычными формами (толстый клиент), наиболее быстрым и действенным способом решения проблемы является установка 64-разрядного клиента платформы 1С.

Разберем по шагам порядок действий:

  1. Проверим разрядность операционной системы на компьютере пользователя. На современных рабочих станциях используется 64-разрядная Windows.
  2. Скачаем дистрибутив «Клиент 1С:Предприятия для Windows (64-bit)» версии, строго совпадающей с версией сервера приложений (например, 8.3.10.2639 или старше).
  3. Выполним установку 64-битного клиента. При установке исполняемые файлы будут размещены в каталоге C:\Program Files\1cv8\ (в отличие от 32-битной версии, которая устанавливается в C:\Program Files (x86)\1cv8\).
  4. Запустим базу данных через установленный 64-битный клиент. Теперь процесс 1cv8.exe сможет адресовать весь объем оперативной памяти рабочей станции и использовать файл подкачки без ограничений в 2 ГБ.
  5. Убедимся, что на системном диске пользователя включен файл подкачки (рекомендуется задать фиксированный размер 4096–8192 МБ, особенно при наличии SSD-диска).

Шаг 2. Настройка лимитов оперативной памяти для MS SQL Server

Проанализируем конфигурацию сервера, если сервер приложений 1С и СУБД Microsoft SQL Server установлены совместно на одном физическом или виртуальном сервере (например, с общим объемом памяти 32 ГБ).

Рассчитаем оптимальное распределение памяти:

  1. Операционная система Windows Server: 4–6 ГБ для стабильной работы системных служб, кэша файловой системы и терминальных сессий.
  2. Кластер серверов 1С:Предприятие (службы ragent, rmngr, rphost): 8–10 ГБ.
  3. Microsoft SQL Server: 16–18 ГБ под буферный пул и кэш планов запросов.

Для ограничения аппетитов СУБД выполним настройку через среду SQL Server Management Studio (SSMS):

  1. Подключимся к экземпляру SQL Server с правами администратора.
  2. В обозревателе объектов (Object Explorer) нажмем правой кнопкой мыши на имени сервера и выберем пункт Свойства (Properties).
  3. Перейдем на страницу Память (Memory).
  4. В поле Максимальный размер памяти сервера (в МБ) (Maximum server memory (in MB)) укажем рассчитанное значение: для выделения 16 ГБ введем 16384, для 18 ГБ — 18432.
  5. Поле Минимальный размер памяти сервера оставим без изменений (по умолчанию 0).
  6. Нажмем ОК. Изменение лимита памяти применяется немедленно без необходимости перезапуска службы SQL Server.

Шаг 3. Тонкая настройка MS SQL Server под специфику 1С

При переносе баз 1С на современные выпуски MS SQL Server (2014, 2016, 2017, 2019) важно адаптировать параметры СУБД, чтобы исключить деградацию планов выполнения запросов.

Выполним следующие оптимизационные команды в окне нового запроса SSMS:


-- 1. Включаем классический оптимизатор планов запросов для базы 1С
USE [Имя_Базы_1С];
GO
ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON;
GO

-- 2. Ограничиваем параллелизм выполнения тяжелых запросов
EXEC sys.sp_configure N'show advanced options', N'1' RECONFIGURE WITH OVERRIDE;
GO
EXEC sys.sp_configure N'max degree of parallelism', N'1';
GO
RECONFIGURE WITH OVERRIDE;
GO

Параметр LEGACY_CARDINALITY_ESTIMATION = ON возвращает алгоритм оценки кардинальности к проверенной логике SQL Server 2012, предотвращая раздувание промежуточных выборок при работе с временными таблицами 1С. Параметр max degree of parallelism = 1 исключает паразитные взаимные блокировки при параллельном расчете запросов на многоядерных процессорах.

Шаг 4. Оптимизация программного кода запроса в конфигураторе 1С

Рассмотрим структуру кода, на котором происходит падение. В модулях подбора номенклатуры (например, Обработка.ПодборНоменклатуры) типовая ошибка заключается в формировании запроса к остаткам без жестких условий в параметрах виртуальной таблицы.

Посмотрим на классический неоптимальный пример, вызывающий переполнение памяти:


// НЕОПТИМАЛЬНЫЙ ВАРИАНТ:
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Номенклатура,
    |	Номенклатура.Код КАК Код,
    |	Номенклатура.Наименование КАК Наименование,
    |	ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) КАК Остаток
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |	ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК ТоварыНаСкладахОстатки
    |		ПО Номенклатура.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
    |ГДЕ
    |	Номенклатура.ЭтоГруппа = ЛОЖЬ";

РезультатЗапроса = Запрос.Выполнить(); // Падение по нехватке памяти при выгрузке

В приведенном фрагменте виртуальная таблица ТоварыНаСкладах.Остатки рассчитывает остатки абсолютно по всей номенклатуре и по всем складам компании, после чего СУБД пытается передать всю эту таблицу в оперативную память клиента.

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


// ОПТИМИЗИРОВАННЫЙ ВАРИАНТ:
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Номенклатура,
    |	Номенклатура.Артикул КАК Артикул,
    |	Номенклатура.Код КАК Код,
    |	Номенклатура.Наименование КАК Наименование,
    |	ЕСТЬNULL(ТоварыОстатки.ВНаличииОстаток, 0) КАК Остаток
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |	ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
    |		&Период, 
    |		Склад = &ТекущийСклад И Номенклатура В ИЕРАРХИИ (&РодительНоменклатуры)
    |	) КАК ТоварыОстатки
    |		ПО Номенклатура.Ссылка = ТоварыОстатки.Номенклатура
    |ГДЕ
    |	Номенклатура.ВАрхиве = ЛОЖЬ
    |	И Номенклатура.ЭтоГруппа = ЛОЖЬ
    |	И Номенклатура.Ссылка В ИЕРАРХИИ(&РодительНоменклатуры)";

Запрос.УстановитьПараметр("Период", ТекущаяДата());
Запрос.УстановитьПараметр("ТекущийСклад", СкладДокумента);
Запрос.УстановитьПараметр("РодительНоменклатуры", ВыбраннаяПапкаНоменклатуры);

РезультатЗапроса = Запрос.Выполнить();

Разберем ключевые правила оптимизации запросов выборки:

  1. Передача фильтров в параметры виртуальных таблиц: Условия по складу, организации, номенклатуре или периоду обязательно должны передаваться во втором параметре метода Остатки() или СрезПоследних(). Это позволяет СУБД отфильтровать записи на этапе чтения индексов, не сканируя весь регистр.
  2. Исключение тяжелых полей: Не следует выбирать в запросах подбора реквизиты с неограниченной длиной, хранилища значений или полные описания номенклатуры, если они не выводятся в текущем списке.
  3. Постраничная выборка и динамические списки: В формах управляемого приложения рекомендуется использовать объект ДинамическийСписок с включенным свойством ДинамическоеСчитываниеДанных. В обычных формах при больших объемах справочников целесообразно использовать механизм постраничного чтения данных с оператором ПЕРВЫЕ N.

Шаг 5. Профилактика: очистка кэша и пересчет итогов

Если ошибка возникает эпизодически при проведении документов за старые периоды, причиной могут быть неактуальные рассчитанные итоги регистров накопления и бухгалтерии.

Выполним регламентные процедуры обслуживания базы данных 1С:

  1. Запустим информационную базу в режиме Конфигуратор с административными правами.
  2. Перейдем в главное меню: Администрирование -> Тестирование и исправление...
  3. Установим флажки на пунктах:
    • Пересчет итогов (актуализирует таблицы итогов регистров, исключая сканирование всей таблицы движений за все годы при проведении документов).
    • Реиндексация таблиц информационной базы.
    • Проверка логической целостности.
  4. Нажмем кнопку Выполнить и дождемся завершения процедуры в окне служебных сообщений.
  5. Очистим локальный кэш конфигурации на рабочих местах пользователей. Для этого закроем все процессы 1С и удалим содержимое каталогов %LocalAppData%\1C\1Cv8\ и %AppData%\1C\1Cv8\ (папки с буквенно-цифровыми GUID-именами).

Комплексное применение указанных мер — установка 64-битного клиента для преодоления лимита 2 ГБ, фиксация памяти MS SQL Server, включение Legacy Cardinality Estimation и наложение параметров в виртуальных таблицах запросов — полностью ликвидирует ошибку нехватки памяти и существенно ускоряет отклик базы данных.

← На главную