Məzmuna keç
Tez Base

Регламентное обслуживание SQL Server под 1С: статистика, индексы и три побочки, о которых забывают

· Dərc edilib: · Yenilənib:

SQL Server SQL Server и PostgreSQL

Симптом знакомый: отчёт, который месяц назад строился 20 секунд, теперь идёт четыре минуты. Данных прибавилось немного, железо то же, код никто не трогал. Первая мысль - “1С тормозит, нужен сервер помощнее”. На деле чаще всего это база, которая давно живёт без регламентного обслуживания: оптимизатор SQL Server строит планы запросов по устаревшей статистике и выбирает заведомо плохие способы выполнения.

Разберём, что именно нужно обслуживать в базе 1С, как часто, чем REBUILD отличается от REORGANIZE, почему “перестраивать всё каждую ночь” - плохая идея, и что на самом деле делает “Тестирование и исправление” из конфигуратора (спойлер: не то, что от него ждут).

Будут и числа с живого прогона по двум рабочим базам: статистика, которой 97 дней, 598 запросов со сканами, журнал в 73 % от данных. С чего начинать на таком сервере, разобрано перед рабочим планом.

Что деградирует со временем

В базе 1С без обслуживания портятся две разные вещи, и путать их не стоит.

Статистика - сводка о распределении значений в колонках. По ней оптимизатор решает, как выполнять запрос: пройти по индексу или просканировать таблицу, соединить методом вложенных циклов или хешем, сколько памяти запросить под сортировку. Устаревшая статистика = решения принимаются по картине мира годичной давности.

Фрагментация индексов - физический беспорядок: логический порядок страниц не совпадает с физическим, страницы заполнены наполовину. Приводит к лишним чтениям с диска и раздутому кэшу.

Практический вывод, который экономит много ночей: статистика важнее фрагментации. Фрагментированный индекс с хорошей статистикой замедлит запрос в разы; актуальный индекс с протухшей статистикой может замедлить его в сотни раз - потому что план будет принципиально другим. При этом обновление статистики стоит дёшево, а перестроение индексов - дорого. Начинать надо со статистики. И не думать, что свежая статистика надолго: на учётной базе, которую мы обслуживали, за три дня после обновления горячие таблицы изменились до 39 %, и планы опять поехали (кейс про общий сервер).

Почему автообновление статистики не спасает базу 1С

На базе обычно включено AUTO_UPDATE_STATISTICS - и это создаёт ложное чувство безопасности. Порог срабатывания: для таблиц больше 500 строк статистика считается устаревшей после изменения примерно 20 % строк (в новых версиях SQL Server порог для больших таблиц динамический и мягче, но всё равно измеряется процентами).

Посчитаем на реальном масштабе. Таблица движений регистра на 50 млн строк: чтобы сработало автообновление, нужно изменить около 10 млн строк. При обычном темпе работы - десятки тысяч документов в месяц - это годы. То есть на самых больших и самых горячих таблицах автообновление практически не срабатывает никогда, а именно на них и живут все тяжёлые запросы.

Второй нюанс - точность. Автообновление считает статистику по выборке (sample), а не по всей таблице. На неравномерных данных (а в 1С они почти всегда неравномерные: 90 % документов по одной организации, товар-локомотив с миллионом движений) выборка врёт. Регулярный UPDATE STATISTICS ... WITH FULLSCAN по ключевым таблицам снимает этот класс проблем.

Посмотреть, когда статистика обновлялась в последний раз и сколько строк изменилось с тех пор:

-- Насколько протухла статистика: топ-30 самых "просроченных" объектов
SELECT TOP (30)
    OBJECT_NAME(s.object_id)      AS таблица,
    s.name                        AS статистика,
    sp.last_updated               AS обновлена,
    sp.rows                       AS строк,
    sp.modification_counter       AS изменений_с_тех_пор,
    CAST(100.0 * sp.modification_counter / NULLIF(sp.rows, 0) AS DECIMAL(6,2)) AS процент
FROM sys.stats AS s
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp
WHERE OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1
  AND sp.rows > 100000
ORDER BY sp.modification_counter DESC;

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

Если сервер старый

Функция sys.dm_db_stats_properties по документации Microsoft есть в SQL Server 2008 R2 начиная с SP2 и в 2012 начиная с SP1. Где её нет, возраст статистики показывает STATS_DATE, без счётчика изменений, но с датой. Так сняты и числа нашего прогона: самой старой статистике на таблицах от 100 тысяч строк было 97 дней, а из 21 статистики старше месяца все были старше и трёх месяцев.

-- Возраст статистики через STATS_DATE, без sys.dm_db_stats_properties.
-- Выполнять в базе 1С: sys.stats и sys.partitions показывают только текущую базу.
SELECT TOP (30)
    OBJECT_NAME(s.object_id)                                      AS таблица,
    s.name                                                        AS статистика,
    STATS_DATE(s.object_id, s.stats_id)                           AS обновлена,
    DATEDIFF(day, STATS_DATE(s.object_id, s.stats_id), GETDATE()) AS дней_назад,
    p.rows                                                        AS строк
FROM sys.stats AS s
JOIN sys.objects AS o
    ON o.object_id = s.object_id
JOIN (SELECT object_id, SUM(rows) AS rows
      FROM sys.partitions
      WHERE index_id IN (0, 1)          -- куча или кластерный индекс: строки таблицы
      GROUP BY object_id) AS p
    ON p.object_id = s.object_id
WHERE o.type = 'U'
  AND p.rows > 100000
  AND STATS_DATE(s.object_id, s.stats_id) IS NOT NULL
ORDER BY дней_назад DESC;

Индексы: REORGANIZE или REBUILD

Фрагментацию лечат двумя операциями, и разница между ними принципиальна.

REORGANIZE - дефрагментация на месте, всегда онлайн, работает порциями, её можно прервать без отката. Не обновляет статистику. Подходит при умеренной фрагментации.

REBUILD - перестроение индекса заново. Дороже, требует места, в редакции Standard по умолчанию офлайн - то есть с исключительной блокировкой таблицы на всё время операции. Зато попутно пересчитывает статистику по всем строкам - фактически бесплатный FULLSCAN по индексным колонкам.

Общепринятые пороги (ориентир, не догма): фрагментация до 5 % - не трогать, 5-30 % - REORGANIZE, больше 30 % - REBUILD. И отдельное правило: мелкие индексы (меньше 1000 страниц, ~8 МБ) обслуживать бессмысленно - они целиком живут в кэше, фрагментация на них ни на что не влияет.

Оценить реальную картину:

-- Фрагментация индексов: только то, что действительно стоит обслуживать
SELECT
    OBJECT_NAME(ips.object_id)                     AS таблица,
    i.name                                         AS индекс,
    CAST(ips.avg_fragmentation_in_percent AS DECIMAL(5,2)) AS фрагментация,
    ips.page_count                                 AS страниц,
    CASE
        WHEN ips.avg_fragmentation_in_percent > 30 THEN 'REBUILD'
        WHEN ips.avg_fragmentation_in_percent > 5  THEN 'REORGANIZE'
        ELSE 'пропустить'
    END                                            AS действие
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ips
JOIN sys.indexes AS i
    ON i.object_id = ips.object_id AND i.index_id = ips.index_id
WHERE ips.page_count > 1000            -- мелочь не трогаем
  AND ips.index_id > 0                 -- кучи пропускаем
  AND ips.avg_fragmentation_in_percent > 5
ORDER BY ips.page_count DESC;

Обратите внимание на режим 'LIMITED' - он читает только верхний уровень индекса и почти не нагружает сервер. Режим 'DETAILED' на терабайтной базе способен занять дисковую подсистему на часы; на бою его запускать не надо.

Три побочки ночного обслуживания

Здесь чаще всего и случаются неприятности: администратор ставит “перестраивать все индексы каждую ночь”, и вместо ускорения получает новые проблемы.

1. Журнал транзакций. REBUILD в модели восстановления FULL логируется полностью. Перестроение индексов на терабайтной базе способно за ночь сгенерировать журнал больше самой базы - со всеми последствиями: раздутый LDF, переполненный диск, долгая ночная цепочка бэкапов журнала. Как это разгребать, если уже случилось - в статье “Журнал транзакций 1С разросся”.

2. tempdb. Опция SORT_IN_TEMPDB = ON ускоряет перестроение, но переносит сортировку в tempdb - и та должна быть к этому готова по размеру и скорости дисков. Если tempdb настроена “как получилось”, ночное обслуживание отлично умеет ронять её в ошибку 9002.

3. Блокировки. Офлайн-REBUILD держит исключительную блокировку таблицы. Если окно обслуживания наложилось на ночные фоновые задания, обмены или на пользователей из другого часового пояса - они встанут намертво и получат таймауты. Механику ожиданий разбирали в статье про блокировки в 1С.

Плюс четвёртое, косвенное: после массового перестроения индексов резко растёт объём дифференциальных бэкапов (изменились почти все страницы). Если ночью же идёт бэкап - он внезапно станет длиннее, см. “Бэкап 1С идёт всю ночь”.

Отсюда главное правило: обслуживание должно быть условным (по порогам, а не “всё подряд”) и ограниченным по времени - с окном, за которое оно обязано уложиться.

Что делает и чего не делает “Тестирование и исправление”

Регулярная путаница, которая стоит компаниям ночей простоя. “Тестирование и исправление информационной базы” в конфигураторе - инструмент логической целостности данных 1С: битые ссылки, потерянные объекты, несоответствие структуры. Он не занимается производительностью СУБД.

  • Пункт “Реиндексация таблиц информационной базы” в ТиИ - это не то же самое, что обслуживание индексов SQL Server. Он пересоздаёт индексы, которые платформа считает своими, и не заменяет ни REBUILD по порогам, ни обновление статистики.
  • ТиИ требует монопольного режима и на большой базе идёт часами. Запускать его “на всякий случай раз в месяц” - дорого и бессмысленно.
  • Правильный повод для ТиИ - подозрение на повреждение данных: ошибки при проведении, битые ссылки в отчётах, сбой оборудования.

Проверка физической целостности - это другая операция и другой инструмент:

-- Физическая целостность базы: раз в месяц, в окно обслуживания
DBCC CHECKDB ('ваша_база') WITH NO_INFOMSGS, ALL_ERRORMSGS;

На больших базах CHECKDB дорогой - его часто гоняют не на проде, а на восстановленной из бэкапа копии. Заодно это единственный честный тест “а бэкап-то рабочий?”. Если проверка нашла ошибки, не спешите с REPAIR_ALLOW_DATA_LOSS: что сохранить до исправления и как по номеру индекса понять, что пропало в 1С, разобрано в статье CHECKDB нашёл ошибки в базе 1С.

До плана обслуживания: что ещё показывает прогон по серверу

Регламент из следующего раздела закрывает статистику и индексы, а четыре вещи ниже им не лечатся. Прогон шёл на сервере с 64 ядрами и примерно 580 сеансами, по двум базам: боевой и малонагруженной.

Запросы со сканами. Кэш планов (sys.dm_exec_query_stats) на боевом сервере показал 598 запросов, читающих больше миллиона страниц за вызов. Самый дорогой набрал 781 386 секунд процессора за 104 760 выполнений, по 7,5 секунды на вызов. А 261 запрос отработал миллион раз и больше, так обычно выглядит запрос в цикле. Кэш копится с перезапуска: аптайм был 7 022 часа, после свежей перезагрузки те же цифры ничего бы не значили. Имена _Reference123 и _AccumRgT456 в тексте запросов переводит в объекты конфигурации обработка SQL-запрос в термины 1С.

Журнал транзакций. На второй базе журнал весил 11 464 МБ при 15 624 МБ данных, 73 %. Что мешает ему освобождаться, называет log_reuse_wait_desc, и два частых значения лечатся противоположно. LOG_BACKUP: журнал ждёт очередной копии, а без копий растёт до конца диска. ACTIVE_TRANSACTION: его держит открытая транзакция, копия не поможет. На боевом сервере прогон застал оба, первое у базы 1С, второе у tempdb. Самой старой из 83 активных транзакций было 69 секунд, открыл её 1CV83 Server, а для 1С и минута долго. Обе ветки разобраны в статье журнал транзакций 1С разросся.

tempdb. Документация Microsoft советует столько файлов данных, сколько логических процессоров, но для начала не больше восьми, одного размера и прироста. С одним файлом под нагрузкой сеансы встают в очередь за страницами выделения (PAGELATCH_UP). На сервере прогона при 64 ядрах файлов было восемь, как и советует документация. Чем занято место, видно так:

-- Чем занята tempdb. Представление читается из самой tempdb, фильтр по базе не нужен.
SELECT
    SUM(user_object_reserved_page_count)     * 8 / 1024 AS временные_таблицы_мб,
    SUM(internal_object_reserved_page_count) * 8 / 1024 AS сортировки_и_хеши_мб,
    SUM(version_store_reserved_page_count)   * 8 / 1024 AS version_store_мб,
    SUM(unallocated_extent_page_count)       * 8 / 1024 AS свободно_мб
FROM tempdb.sys.dm_db_file_space_usage;

Место под временные таблицы съедают пакетные запросы с ПОМЕСТИТЬ, под сортировки и хеши отчёты без подходящего индекса. Растущий version store при RCSI означает длинную транзакцию, её и ищут, как в разборе ошибки 9002 в tempdb.

Ожидания. В топе боевого сервера CXCONSUMER 38,2 %, CXSYNC_PORT 26,0 % и CXPACKET 17,0 %, вместе 81 % на параллелизм. Только значения там уже не заводские, MAXDOP 4 и порог 100, а при таких настройках CX-ожидания значат лишь, что параллельные планы есть. Дорога дальше к тяжёлым запросам из первого пункта. Счётчики ожиданий, как и кэш планов, копятся с перезапуска.

Если собираете диагностику сами

Неверная колонка роняет весь пакет: имена SQL Server проверяет при компиляции, и TRY/CATCH того же пакета ошибку 207 не ловит. Так у нас разом не отработали все проверки: total_physical_memory_kb искали в sys.dm_os_sys_info, а она лежит в sys.dm_os_sys_memory. Зависящее от версии гоняйте через sp_executesql, его ошибку компиляции CATCH ловит. Накопитель делайте временной таблицей #o: табличную переменную динамический SQL не видит.

Ошибка 451 на UNION ALL случается, когда встречаются строковые колонки разных сортировок, литералы её не вызывают. Мы воспроизвели её на SQL Server 2022, где сервер и база в Cyrillic_General_CI_AS, склеив wait_type с log_reuse_wait_desc: у второй колонки сортировка Latin1_General_CI_AS_KS_WS. Одинаковая сортировка сервера и базы от 451 не страхует, лечит COLLATE DATABASE_DEFAULT у каждой строковой колонки.

Из топа ожиданий исключайте фон: SLEEP_TASK, LAZYWRITER_SLEEP, XE_TIMER_EVENT, BROKER_TRANSMITTER, HADR_NOTIFICATION_DEQUEUE и обязательно SOS_WORK_DISPATCHER, на боевом сервере он один забирал до 39 %.

Рабочий план обслуживания

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

Схема, которая закрывает 90 % потребностей средней базы 1С и не требует экзотики:

ЧтоКак частоОкноКомментарий
UPDATE STATISTICS по горячим таблицам, FULLSCANежедневноночь, 15-40 минсамое дешёвое и самое полезное
Обслуживание индексов по порогам (5/30 %)еженедельновыходныетолько page_count > 1000
DBCC CHECKDBежемесячнопо копии из бэкапаили на проде, если влезает в окно
Проверка восстановления бэкапаежемесячнотестовый сервербэкап без теста - не бэкап
Ревизия неиспользуемых индексовежеквартально-лишние индексы замедляют запись

Несколько практических деталей:

  • Обслуживание индексов не запускается в модели FULL без бэкапов журнала - сначала настройте цепочку бэкапов, иначе получите LDF на пол-диска.
  • Ограничьте MAXDOP для операций обслуживания, если ставите его в 1 для рабочей нагрузки: перестроение индекса выигрывает от параллелизма (у REBUILD есть свой WITH (MAXDOP = n)), в отличие от коротких запросов 1С - почему так, разбирали в статье про блокировки.
  • Скрипты не пишите с нуля. Готовые решения по обслуживанию по порогам (тот же широко известный набор Ola Hallengren) давно отлажены; ваша задача - настроить пороги, окна и мониторинг результата, а не изобретать логику.
  • Регламентные задания 1С и задания SQL Agent - разные слои. Первые про прикладную логику (пересчёт итогов, обмены, закрытие периодов), вторые про СУБД. Складывать обслуживание индексов в регламентные задания 1С не нужно.

Как понять, что обслуживание вообще помогло

Обслуживание без замера - ритуал. Минимальный набор доказательств:

  1. Время конкретных операций до и после - не “база стала быстрее”, а “формирование отчёта по остаткам: было 3 мин 40 с, стало 22 с”.
  2. Планы запросов - если после обновления статистики оптимизатор сменил вложенные циклы на хеш-соединение, вы увидите это в плане и в числе логических чтений.
  3. Длительность самого окна обслуживания - если оно растёт от недели к неделе, пороги подобраны неверно либо база требует уже не обслуживания, а сокращения объёма.

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

И не доверяйте статусу задания на слово: “выполнено успешно” в планировщике означает лишь, что процесс завершился без ошибки, а не что обслуживание реально прошло. Как цепочки заданий месяцами рапортуют успех без единого сделанного дела и какими пятью проверками это ловится - в разборе про выгрузку по расписанию, которая не работала.

Чек-лист

  1. Проверьте last_updated статистики по крупным таблицам - если там прошлый год, это ваша главная причина медленных запросов.
  2. Ежедневное обновление статистики по горячим таблицам важнее еженедельного перестроения индексов.
  3. Обслуживайте индексы по порогам и только те, что больше 1000 страниц.
  4. Учтите побочки: журнал транзакций, tempdb, блокировки, размер бэкапов.
  5. REBUILD попутно даёт полную статистику - не делайте её дважды.
  6. ТиИ из конфигуратора - про целостность данных, а не про производительность.
  7. Меряйте эффект контрольными операциями, а не ощущениями.

Если база уже месяцами живёт без регламента и непонятно, с чего начинать - начните с бесплатного экспресс-аудита: снимем фрагментацию, возраст статистики и фактические узкие места по монитору СУБД, покажем, что даст обслуживание, а что потребует работы с кодом или объёмом. Регулярное сопровождение баз с окнами обслуживания и контролем результата - услуга обслуживание баз 1С.

Готовая обработка по теме

Проверить всё это одним прогоном, не собирая скрипты руками, помогает Чек-ап СУБД под 1С: 40+ проверок настроек SQL Server с вердиктом по каждой и готовым скриптом для администратора (на странице есть демо-отчёт на боевой базе).

Bunu sizin əvəzinizə həll edə bilərəm

Reqlament xidmətini elə qururuq ki, baza stabil işləsin, ehtiyat nüsxələr zəmanətlə bərpa olunsun, disklərdəki yer isə qəfil bitməsin.

Qiyməti
450 000 ₸-dənbirdəfəlik sazlama; müşayiət - ayda 150 000 ₸-dən; vergilərsiz

Yazmaq tezdir? Özünüz ölçün

Чек-ап СУБД под 1С: 40+ проверок с вердиктом по каждой

Emalı aç

INFOSTART TECH EVENT 2026: конференция для 1с-специалистов. если собираетесь, регистрируйтесь по нашей ссылке. Регистрация →

Bunu da oxuyun

База 1С не открывается после обновления конфигурации: порядок действий, когда копии нет

Конфигуратор пишет "При обновлении данных, после последней реструктуризации, произошла критическая ошибка", пользователи в базу не попадают, копии до обновления нет. Разбираем по шагам: что сохранить первым, как по журналу регистрации найти этап, на котором упало, какие действия только добавляют ошибок, когда бросать починку старой базы и как через ibcmd выгрузить .dt из базы, которая не открывается, собрать новую и тихо подменить её в кластере. В конце - задания резервного копирования, после которых такая авария превращается в откат на минуту до обновления.

Остатки в 1С не сходятся с движениями: как найти сломанный месяц итогов и не пересчитывать всю историю

Отчёт по движениям даёт одно число, запрос к остаткам другое, перепроведение ничего не меняет. Разбираем, как отличить сломанные итоги от ошибки в движениях, каким запросом найти позицию и месяц расхождения, почему строку итогов на 1 августа чинит пересчёт за август, а не за июль, в каком порядке пересчитывать текущие итоги и как посмотреть саму строку итогов на SQL. Все шаги проверены на тестовой копии УТ 11.5 с испорченной строкой.

CHECKDB нашёл ошибки в базе 1С: порядок действий до REPAIR и после

CHECKDB советует repair_allow_data_loss и на битый индекс, и на потерянные документы. Разбираем по шагам, что делать в первый час: что сохранить до исправления, как по таблице и номеру индекса понять, что задето в 1С, как перестроить битый индекс без потерь и как получить список пропавших документов, пока REPAIR не удалил их молча. Проверено на копии УТ для Казахстана с испорченными страницами.