Зависание сеанса 1С при выполнении, казалось бы, простейшего запроса — ситуация, с которой часто сталкиваются администраторы и разработчики систем, интегрированных с ФГИС «Меркурий». Особенно остро проблема проявляется в справочнике ВетеринарноСопроводительныйДокументВЕТИС, который в активных базах разрастается до внушительных размеров. В этой статье мы подробно разберем, почему запрос с условием ГДЕ может «повесить» систему, в то время как запрос без условий работает мгновенно, и как вернуть базе былую производительность.
Рассмотрим типовую ситуацию: при выполнении простого запроса на получение количества документов по определенному статусу сеанс пользователя замирает. При этом консоль запросов не выдает результат даже спустя 10-20 минут. Если же убрать условие фильтрации, данные возвращаются быстро. Посмотрим на пример проблемного кода:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВСД.Ссылка) КАК КоличествоДокументов
ИЗ
Справочник.ВетеринарноСопроводительныйДокументВЕТИС КАК ВСД
ГДЕ
ВСД.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыВетеринарныхДокументовВЕТИС.Оформлен)
Почему так происходит? Выясним причину. Когда мы запрашиваем данные без условий, SQL Server часто выполняет быстрое сканирование индекса или заголовков таблицы. Но как только появляется условие ГДЕ по неиндексированному полю, СУБД вынуждена прочитать каждую строку таблицы с диска, чтобы проверить её на соответствие фильтру. Для справочников ВЕТИС, где каждая запись может содержать объемные XML-данные, это превращается в колоссальную нагрузку на дисковую подсистему.
Однако основная коварность проблемы кроется в устаревшей статистике. SQL Server строит план выполнения запроса, опираясь на свои «знания» о распределении данных. Если статистика устарела (например, не обновлялась несколько месяцев), оптимизатор может выбрать в корне неверную стратегию, решив, что документов с нужным статусом всего 10, хотя их на самом деле 300 000. В результате вместо быстрого поиска мы получаем бесконечное ожидание.
Если ваша база данных работает на MS SQL Server и вы столкнулись с внезапным замедлением, первым делом стоит обновить статистику. Как показала практика, это действие в 90% случаев мгновенно снимает проблему зависания.
Рассмотрим шаги для выполнения этой операции:
EXEC sp_updatestats;
UPDATE STATISTICS [_Reference33631];
где _Reference33631 — имя таблицы справочника в SQL.
Важный момент: Обновление статистики — это легкая операция, которую можно выполнять даже во время работы пользователей, она не блокирует данные так, как это делает реиндексация.
Проанализируем структуру справочника ВетеринарноСопроводительныйДокументВЕТИС. Если поле, по которому идет отбор (например, Статус), имеет свойство Индексировать в значении «Не индексировать», то при любом запросе SQL Server будет выполнять полное сканирование таблицы (Table Scan).
Чтобы исправить это, выполним следующие действия:
ВетеринарноСопроводительныйДокументВЕТИС.Статус.После создания индекса SQL Server сможет выполнять Index Seek вместо Table Scan, что сократит количество читаемых данных с миллионов строк до нескольких сотен.
Если обновление статистики и индексы не помогают, а запросы виснут даже в консоли самого SQL Server, нужно убедиться, что база данных не повреждена. Разберем, как проверить таблицу на уровне СУБД.
Воспользуемся командой DBCC CHECKTABLE. Это позволит выяснить, нет ли в таблице битых страниц или логических несоответствий:
DBCC CHECKTABLE('_Reference33631') WITH NO_INFOMSGS, ALL_ERRORMSGS;
Если ошибок не обнаружено, стоит попробовать радикальный, но действенный метод для 1С — выгрузку и загрузку в файл .dt. Это полностью пересобирает базу данных, устраняет фрагментацию на логическом уровне и очищает кэш планов запросов. Однако помните, что для баз объемом более 50-100 Гб этот процесс может занять очень много времени.
Разберем ситуацию, когда зависание сопровождается высоким значением io stall (ожидание ввода-вывода). Если диски не справляются с нагрузкой, любые тяжелые запросы будут приводить к «замиранию» всей системы. Проанализируем показатели монитора ресурсов: если процесс sqlservr.exe активно читает данные из файла tempdb.mdf, это значит, что SQL Server не хватает оперативной памяти для сортировки данных, и он сбрасывает их на диск.
Для оптимизации работы рекомендуем:
TempDB на самый быстрый диск в системе (желательно NVMe SSD).TempDB равным количеству ядер процессора (но не более 8).1, чтобы один «кривой» запрос не захватывал все ресурсы процессора.В завершение проанализируем важность регламентных заданий. Если проблема «ушла сама», скорее всего, ночью отработал стандартный план обслуживания SQL. Чтобы ситуация не повторилась, настройте ежедневное обновление статистики и еженедельную дефрагментацию индексов. Это обеспечит стабильную работу системы даже с такими тяжелыми объектами, как справочники ВЕТИС.