Почему 1С 7.7 работает на MS SQL медленнее, чем на DBF, и как ускорить работу?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Перевод базы данных 1С 7.7 с файлового режима (DBF) на MS SQL Server нередко приводит к неожиданному эффекту: отчёты и проведение документов начинают работать в несколько раз медленнее. В файловом режиме индексы и таблицы активно кэшируются в оперативной памяти клиентской станции или терминального сервера, а выборка выполняется напрямую. В случае с SQL Server стандартный движок 1С 7.7 формирует огромное количество мелких одиночных запросов к базе данных, что создаёт колоссальные накладные расходы на сетевой обмен и обработку каждого запроса на стороне СУБД.

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

Причина 1. Неоптимальная генерация T-SQL запросов платформой

При использовании штатных запросов или переборе объектов в циклах 1С 7.7 обращается к MS SQL Server не одним глобальным запросом, а множеством последовательных вызовов. Например, при формировании отчёта по остаткам система сначала выбирает идентификаторы номенклатуры из регистра, а затем для каждого элемента отдельным запросом запрашивает его наименование и реквизиты из таблицы справочника.

В DBF-версии это происходит мгновенно из локального кэша ОЗУ. В SQL Server каждый такой запрос требует проверки прав, анализа статистики, построения плана выполнения и сетевого круглого хода (round-trip), что при циклах на десятки тысяч строк приводит к замедлению в 5–10 раз.

Причина 2. Неправильная настройка MS SQL Server

По умолчанию MS SQL Server настроен на универсальную нагрузку и не учитывает специфику работы 1С 7.7. Для корректной работы СУБД с семеркой выполним следующие настройки:

  1. Ограничение параллелизма (Max Degree of Parallelism): Для 1С 7.7 необходимо ограничить параллелизм выполнения запросов. Установим параметр MAXDOP = 1 в настройках сервера. В противном случае СУБД тратит больше времени на распараллеливание мелких запросов и ожидание потоков, чем на само выполнение.
  2. Ограничение оперативной памяти: Зададим фиксированное максимальное значение памяти (Max Server Memory) для SQL Server. Если SQL и терминальный сервер работают на одной машине, без ограничения СУБД заберет всю память, либо операционная система начнет выгружать кэш SQL в файл подкачки (pagefile.sys).
  3. Включение Lock Pages in Memory: Назначим учетной записи, под которой запущен SQL Server, право Lock Pages in Memory в локальных политиках безопасности Windows, чтобы предотвратить сброс рабочего множества памяти СУБД на диск.
  4. Настройка TempDB: Вынесем файлы базы tempdb на отдельный быстрый SSD-диск и разобьем tempdb на несколько файлов одинакового размера (по числу ядер процессора).
  5. Протокол Shared Memory: Если 1С 7.7 и MS SQL Server установлены на одном физическом или виртуальном сервере, включим протокол Shared Memory в сетевой конфигурации SQL Server, отключив остальные протоколы для локальных подключений.
  6. Регламентные работы: Настроим регулярное обновление статистики (Update Statistics) и дефрагментацию/реиндексацию таблиц. Неактуальная статистика заставляет оптимизатор SQL выбирать неверные индексы.

Причина 3. Обращение к реквизитам через «точку» и периодические реквизиты в циклах

Проанализируем типовую ошибку в коде 1С 7.7, которая на DBF работает терпимо, а на SQL вызываeт катастрофическое падение производительности:


Пока Запрос.Группировка("Номенклатура") = 1 Цикл
    // Каждое обращение через точку порождает отдельный SQL-запрос
    Ставка = Запрос.Номенклатура.СтавкаНДС.Получить(Запрос.МоментВремени);
    ПечататьСтроку(Запрос.Номенклатура.Наименование, Ставка);
КонецЦикла;

Чтобы устранить эту проблему, перепишем алгоритм с использованием кэширования в память:

  1. Выгрузим необходимые периодические реквизиты или свойства в Таблицу Значений (ТЗ) перед началом цикла один раз.
  2. Внутри цикла будем получать данные из заранее подготовленной ТЗ по значению ключа с помощью НайтиЗначение() или предварительной индексации.
  3. Сократим цепочки обращения к реквизитам: вместо обращения вида Запрос.Док.Номенклатура.СтавкаНДС сначала присвоим объект локальной переменной: Ном = Запрос.Номенклатура;.

Причина 4. Незакрытые регистры сведений и остатков

Выясним еще одну частую причину медленного расчета остатков — наличие «зависших» итогов в таблицах регистров. Если при проведении документов расхода измерения заполняются не так, как при приходе (например, Приход был с указанием измерения Фирма, а Расход — с пустым значением), физический остаток по товару равен нулю, но в таблице итогов RG создаются две записи:

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

Причина 5. Использование прямых запросов (1С++ / ToySQL)

Самый эффективный способ ускорить отчёты и обработку данных в 1С 7.7 на MS SQL Server в десятки и сотни раз — использование прямой работы с СУБД через внешнюю компоненту 1С++ и объект ODBCRecordset.

Прямой запрос выполняются непосредственно на стороне SQL Server в один пасс, задействуя всю мощь T-SQL, соединения таблиц (JOIN) и агрегатные функции, возвращая на клиент уже готовый результат.

Рассмотрим пример выполнения прямого запроса для получения остатков номенклатуры:


ЗапросSQL = СоздатьОбъект("ODBCRecordset");
ТекстЗапроса = "
|SELECT 
|   RGT.sp123 AS [Номенклатура $Справочник.Номенклатура],
|   SUM(RGT.sp124) AS [Остаток]
|FROM 
|   rg122 RGT (NOLOCK)
|WHERE 
|   RGT.period = :Период~
|GROUP BY 
|   RGT.sp123
|HAVING 
|   SUM(RGT.sp124) <> 0
|";

ЗапросSQL.УстановитьТекстовыйПараметр("Период", НачМесяца);
ТЗРезультат = ЗапросSQL.ВыполнитьИнструкцию(ТекстЗапроса);

Использование 1С++ и TurboBL позволяет избавиться от узких мест платформы 7.7 и достичь скорости работы отчетов, превышающей показатели даже файловой версии DBF.

← На главную