Почему файловая база 1С работает значительно медленнее клиент-серверной при открытии списков документов?

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

В процессе разработки и отладки конфигураций в файловом режиме многие разработчики сталкиваются с ситуацией, когда один и тот же запрос в клиент-серверной рабочей базе отрабатывает за доли секунды, а в локальной файловой базе приводит к зависанию интерфейса на минуты. Особенно ярко это проявляется в динамических списках документов и справочников при наличии соединений с другими таблицами.

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

Анализ проблемного запроса динамического списка

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


ВЫБРАТЬ ПЕРВЫЕ 50
    ДокЗаявкаКлиента.Дата,
    ДокЗаявкаКлиента.Номер,
    ДокЗаявкаКлиента.Клиент,
    ДокЗаявкаКлиента.Вес,
    ДокЗаявкаКлиента.Объем,
    ДокЗаявкаКлиента.Стоимость,
    ДокЗаявкаКлиента.СпособПогрузки,
    ДокЗаявкаКлиента.ДатаПогрузкиДляОтбора КАК ДатаПогрузки,
    ДокЗаявкаКлиента.ДатаРазгрузкиДляОтбора КАК ДатаРазгрузки,
    ДокЗаявкаКлиента.ТребованиеКТС,
    ДокЗаявкаКлиента.НазваниеГруза,
    ДокЗаявкаКлиента.ПредоставитьДо,
    ДокЗаявкаКлиента.ПунктОтправленияПредставление КАК ПунктОтправления,
    ДокЗаявкаКлиента.ПунктНазначенияПредставление КАК ПунктНазначения,
    ДокЗаявкаКлиента.Автор,
    ДокЗаявкаКлиента.Клиент.ОсновнойМенеджерПокупателя КАК ОтветственныйМенеджер,
    ДокЗаявкаКлиента.ВторойЛогист,
    ДокЗаявкаКлиента.Ссылка,
    ДокЗаявкаКлиента.Комментарий,
    ДокЗаявкаКлиента.СтоимостьДляПеревозчика,
    ДокЗаявкаКлиента.ТипТС,
    ЕСТЬNULL(уатЗаказГрузоотправителя.Ссылка, ЗНАЧЕНИЕ(Документ.уатЗаказГрузоотправителя.ПустаяСсылка)) КАК Заказ,
    ЕСТЬNULL(СтатусЗаявкиКлиентаСрезПоследних.Статус, ЗНАЧЕНИЕ(Перечисление.СтатусыПредварительнойЗаявки.ПустаяСсылка)) КАК Статус,
    уатЗаказГрузоотправителя.Ответственный КАК ОтветственныйЛогист
ИЗ
    Документ.ЗаявкаКлиента КАК ДокЗаявкаКлиента
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.уатЗаказГрузоотправителя КАК уатЗаказГрузоотправителя
        ПО (ДокЗаявкаКлиента.Ссылка = (ВЫРАЗИТЬ(уатЗаказГрузоотправителя.ДокументОснование КАК Документ.ЗаявкаКлиента)))
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтатусЗаявкиКлиента.СрезПоследних КАК СтатусЗаявкиКлиентаСрезПоследних
        ПО (СтатусЗаявкиКлиентаСрезПоследних.ЗаявкаКлиента = ДокЗаявкаКлиента.Ссылка)

В клиент-серверном режиме (например, под управлением Microsoft SQL Server или PostgreSQL) оптимизатор СУБД строит сложный план выполнения, использует хэш-соединения (Hash Match), адаптивные соединения и кэширование промежуточных данных. Встроенный движок файловой базы 1С (файл 1Cv8.1CD) использует упрощенные алгоритмы соединения и последовательного перебора, из-за чего неоптимальные конструкции приводят к резкому падению скорости.

Ключевые причины падения производительности

Проанализируем конкретные узкие места в представленном запросе и архитектуре файлового движка:

  1. Конструкция ВЫРАЗИТЬ в условии соединения. Использование функции ВЫРАЗИТЬ(уатЗаказГрузоотправителя.ДокументОснование КАК Документ.ЗаявкаКлиента) в условии ПО делает предикат неоптимизируемым. Файловый движок не может использовать индекс по реквизиту ДокументОснование составного типа, так как к полю применяется функция преобразования типов. В результате платформа выполняет полное сканирование таблицы заказов на каждую строку заявок.
  2. Соединение со срезом последних без включенного хранения итогов. Виртуальная таблица СрезПоследних при отсутствии рассчитанных итогов разворачивается платформой во вложенный подзапрос с группировкой по максимальной дате. В файловом режиме соединение физической таблицы с неиндексированным подзапросом приводит к катастрофическому замедлению.
  3. Неявные соединения через точку. Обращение к реквизиту ДокЗаявкаКлиента.Клиент.ОсновнойМенеджерПокупателя формирует дополнительное неявное левое соединение со справочником клиентов, что увеличивает объем оперативной обработки при каждом обновлении списка.
  4. Логическая ошибка кратности связи. Соединение с таблицей уатЗаказГрузоотправителя по документу-основанию потенциально порождает связь «один-ко-многим». Если по одной заявке введено несколько заказов, строки списка задваиваются, что нарушает целостность ключей динамического списка и перегружает механизм позиционирования платформы.

Способы оптимизации и решения проблемы

1. Настройка хранения итогов регистра сведений

Выясним, как ускорить работу с виртуальной таблицей среза. Для периодических регистров сведений платформа 1С предоставляет механизм хранения актуальных срезов. Если в свойствах регистра сведений включен режим «Итоги и агрегаты» (хранение итогов), платформа физически поддерживает актуальную таблицу последних записей. В этом случае обращение к таблице СрезПоследних выполняется напрямую к физической таблице итогов с использованием штатных индексов, без динамического вычисления максимальных дат через подзапросы.

2. Избавление от ВЫРАЗИТЬ в условии соединения

Для устранения полного сканирования таблицы привяжем документы через явный ссылочный тип. Если реквизит ДокументОснование имеет составной тип данных, рекомендуется:

  1. Сузить тип реквизита до конкретного документа (если бизнес-логика позволяет).
  2. Добавить в подчиненный документ отдельный реквизит конкретного типа ДокументСсылка.ЗаявкаКлиента с установленным свойством «Индексировать» и соединять таблицы напрямую по равенству ссылок:
    
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.уатЗаказГрузоотправителя КАК уатЗаказГрузоотправителя
    ПО (уатЗаказГрузоотправителя.ЗаявкаКлиента = ДокЗаявкаКлиента.Ссылка)
    

3. Проверка настроек динамического списка

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

  1. Основная таблица: обязательно укажем в свойствах динамического списка основную таблицу (в данном случае Документ.ЗаявкаКлиента). Если свойство не заполнено, платформа не может применять оптимизированное постраничное динамическое считывание порциями по 20–40 строк и считывает весь объем данных целиком.
  2. Динамическое считывание данных: проверим, чтобы флаг динамического считывания был активен. Учтем, что платформа автоматически отключает этот режим, если в настройках списка включены итоги по колонкам или пользовательские группировки.

4. Сервисные операции с файловой базой данных

При частой реструктуризации и доработке конфигурации файл базы данных .1CD подвержен внутренней фрагментации. Для восстановления быстродействия файлового хранилища выполним следующие шаги:

  1. Запустим конфигуратор и откроем меню «Администрирование» — «Тестирование и исправление...».
  2. Установим флаги «Реиндексация таблиц информационной базы» и «Сжатие таблиц информационной базы». Это перестроит все служебные индексы и удалит пустые фрагментированные страницы.
  3. Отключим полнотекстовый поиск в тестовой базе через «Администрирование» — «Управление полнотекстовым поиском», так как фоновое обновление индекса на медленных жестких дисках монопольно занимает дисковую подсистему.
  4. Очистим локальный пользовательский кэш конфигурации в каталогах %LOCALAPPDATA%\1C\1cv8 и %APPDATA%\1C\1cv8.
← На главную