Первый раз запрос выполняется 30 секунд, а потом 3 секунды: почему так происходит и как оптимизировать?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработки на платформе 1С программисты часто сталкиваются с ситуацией, когда при первом формировании отчета или запуске обработки запрос выполняется десятки секунд (например, 30 секунд), а при повторных вызовах — всего за 3 секунды или даже быстрее. Проанализируем физические причины такого поведения системы и рассмотрим комплексы мер по оптимизации.

Выясним причину: почему «первый» раз выполняется намного дольше?

Различие во времени выполнения между первым («холодным») и последующими («горячими») запусками обусловлено несколькими ключевыми механизмами работы СУБД и сервера приложений 1С:

  1. Кэширование данных в буферном пуле (Buffer Pool): При первом запуске СУБД еще не имеет нужных страниц таблиц и индексов в оперативной памяти (RAM). Запрос вынужден выполнять операции физического чтения с диска, что на порядок медленнее обращения к ОЗУ. После первого прохода считанные блоки остаются в памяти, и все последующие обращения происходят из кэша.
  2. Компиляция и кэширование плана выполнения (Plan Cache): Когда СУБД получает новый SQL-запрос, оптимизатор затрачивает ресурсы на построение и компиляцию оптимального плана выполнения. Скомпилированный план сохраняется в процедурном кэше СУБД и при последующих параметризованных вызовах переиспользуется мгновенно.
  3. Кэширование на уровне операционной системы: Даже если данные вытеснены из памяти СУБД, часть из них может оставаться в системном файловом кэше ОС, что снижает время повторной загрузки.
  4. Вымывание кэша ночными процедурами: В ночное время на сервере БД часто выполняются тяжелые регламентные операции (резервное копирование, дефрагментация индексов, обновление статистики). Они считывают огромные объемы данных и вытесняют «дневной» рабочий кэш пользователей.
  5. Инициализация метаданных в сеансе 1С: При первом вызове объекта или таблицы в сеансе пользователя сервер 1С считывает и кэширует структуру метаданных в собственной памяти.

Оптимизация текста запроса в 1С

Даже если повторный запрос выполняется за 3 секунды благодаря кэшу, это не означает, что текст запроса оптимален. Высокое число чтений при холодном старте указывает на несовершенство структуры запроса. Проанализируем типовые ошибки и варианты их исправления.

1. Устранение разыменования полей через точку (неявных соединений)

Рассмотрим фрагмент кода, где в секции условий используется обращение через точку к реквизиту ссылочного поля:

И НЕ Мед_ТалоныПриема.Регистратор.НеВключатьВРеестры

Такое обращение заставляет платформу 1С формировать неявное левое соединение со ВСЕМИ возможными таблицами документов, которые могут выступать в качестве типе составной ссылки Регистратор. Если тип составной или содержит множество документов, это существенно усложняет план SQL и приводит к избыточным чтениям.

Для исправления заменим неявное обращение на явное соединение с конкретной таблицей документа и применим ограничение типа с помощью ССЫЛКА:


ВЫБРАТЬ РАЗЛИЧНЫЕ
    Мед_ТалоныПриема.Регистратор КАК Регистратор
ПОМЕСТИТЬ втТалоныПриемаИсх
ИЗ
    РегистрСведений.Мед_ТалоныПриема КАК Мед_ТалоныПриема
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.Мед_СтатТалон КАК ТотСамыйДокумент
        ПО Мед_ТалоныПриема.Регистратор = ТотСамыйДокумент.Ссылка
            И (ТотСамыйДокумент.НеВключатьВРеестры)
        ЛЕВОЕ СОЕДИНЕНИЕ втИсключаемыеТалоны КАК втИсключаемыеТалоны
        ПО Мед_ТалоныПриема.Регистратор = втИсключаемыеТалоны.Регистратор
ГДЕ
    Мед_ТалоныПриема.Период МЕЖДУ &ДатаНачала И &ДатаКонца
    И Мед_ТалоныПриема.Регистратор ССЫЛКА Документ.Мед_СтатТалон
    И Мед_ТалоныПриема.ИФ = 2
    И Мед_ТалоныПриема.СМООМС = &Организация
    И втИсключаемыеТалоны.Регистратор ЕСТЬ NULL

2. Индексирование временных таблиц

Если временная таблица используется далее в соединениях с другими таблицами (особенно с большими объемами данных), ее необходимо проиндексировать по полям связи. Это позволяет СУБД применять эффективные алгоритмы соединения (например, Index Seek вместо сканирования):


ВЫБРАТЬ РАЗЛИЧНЫЕ
    Мед_ИспользованиеДокументовВРеестрах.Документ КАК Регистратор
ПОМЕСТИТЬ втИсключаемыеТалоны
ИЗ
    РегистрСведений.Мед_ИспользованиеДокументовВРеестрах КАК Мед_ИспользованиеДокументовВРеестрах
ГДЕ
    Мед_ИспользованиеДокументовВРеестрах.Период >= &ДатаКонцаМинус6Месяца
    И Мед_ИспользованиеДокументовВРеестрах.ВидСтрахования <> ЗНАЧЕНИЕ(Перечисление.Мед_ВидыСтрахования.ПустаяСсылка)
    И Мед_ИспользованиеДокументовВРеестрах.Документ ССЫЛКА Документ.Мед_СтатТалон
ИНДЕКСИРОВАТЬ ПО
    Регистратор

Административные методы решения проблемы «холодного» старта

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

  1. Настройка прогрева кэша (Warm-up): Создадим регламентное фоновое задание в 1С, которое запускается по расписанию за 30–60 минут до прихода сотрудников. Это задание может выполнять ключевые тяжелые отчеты или выборки, тем самым загружая необходимые таблицы СУБД с диска в оперативную память.
  2. Настройка оперативной памяти и закрепление страниц: Убедимся, что СУБД выделено достаточное количество ОЗУ, чтобы рабочие данные не вытеснялись из Buffer Pool. В ОС Windows Server включим право Lock Pages in Memory («Закрепление страниц в памяти») для учетной записи службы SQL Server.
  3. Корректировка регламентов обслуживания СУБД: Перенесем тяжелые операции (переиндексацию, бэкапы) на более раннее ночное время, чтобы после их завершения оставалось время на фоновый прогрев. Сразу после переиндексации обязательно выполняем обновление статистики СУБД.
  4. Анализ плана выполнения запроса: При исследовании производительности замеры следует делать с помощью технологического журнала 1С или средства SQL Server Profiler / Extended Events. Основное внимание уделяем показателю логических чтений (Logical Reads) и операторам сканирования (Clustered Index Scan / Table Scan) в плане выполнения.
← На главную