Середина квартала, бухгалтерия готовит отчетность. 1С начинает "виснуть" при формировании счетов. Оказалось — фрагментация индексов достигла 85%. Настроил ночную перестройку индексов в 5:00, и проблема ушла.
📞 Звонок от главбуха: "1С зависает при проведении документов, открытие счета — 3 минуты, сотрудники стоят, клиенты ждут счета!"
* При такой фрагментации SQL Server вместо быстрого поиска по индексу делает полный перебор (table scan), что и вызывает тормоза.
🔧 SQL-запрос для проверки фрагментации (MS SQL):
SELECT
OBJECT_NAME(ind.OBJECT_ID) AS TableName,
ind.name AS IndexName,
indexstats.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstats
JOIN sys.indexes ind ON ind.object_id = indexstats.object_id
AND ind.index_id = indexstats.index_id
WHERE indexstats.avg_fragmentation_in_percent > 30
ORDER BY indexstats.avg_fragmentation_in_percent DESC
Результат: 12 индексов с фрагментацией >70%, 3 индекса >85%.
Перестройка индексов (Rebuild) — ресурсоемкая операция. В нагруженной базе 28 ГБ она может занять от 2 до 4 часов. Делать это днем — парализовать работу офиса.
22 пользователя работают активно. Перестройка индексов заблокирует таблицы, 1С "ляжет".
Пользователей нет, но есть резервное копирование и обновления. Нужно выбрать слот.
Бэкапы сделаны, до начала рабочего дня 3 часа. Как раз хватит на перестройку.
| Платформа | Способ | Комментарий |
|---|---|---|
| MS SQL Server | SQL Server Agent Job с T-SQL скриптом | Гибкая настройка, логирование, обработка ошибок |
| PostgreSQL | pg_cron или внешний планировщик (cron) | VACUUM и REINDEX |
| Файловая 1С | Запуск скрипта через планировщик Windows (chdbfl.exe) | Тестирование и исправление (с опцией "Реиндексация") |
📅 SQL Agent Job (запуск в 05:00 ежедневно):
-- Фрагментация >30% - реорганизация (ALTER INDEX REORGANIZE)
-- Фрагментация >50% - перестройка (ALTER INDEX REBUILD)
DECLARE @TableName NVARCHAR(255)
DECLARE @IndexName NVARCHAR(255)
DECLARE @Fragmentation FLOAT
DECLARE index_cursor CURSOR FOR
SELECT
OBJECT_NAME(ips.object_id) AS TableName,
i.name AS IndexName,
ips.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') ips
JOIN sys.indexes i ON ips.object_id = i.object_id AND ips.index_id = i.index_id
WHERE ips.avg_fragmentation_in_percent > 30
AND i.name IS NOT NULL
OPEN index_cursor
FETCH NEXT FROM index_cursor INTO @TableName, @IndexName, @Fragmentation
WHILE @@FETCH_STATUS = 0
BEGIN
IF @Fragmentation > 50
EXEC ('ALTER INDEX [' + @IndexName + '] ON [' + @TableName + '] REBUILD')
ELSE
EXEC ('ALTER INDEX [' + @IndexName + '] ON [' + @TableName + '] REORGANIZE')
FETCH NEXT FROM index_cursor INTO @TableName, @IndexName, @Fragmentation
END
CLOSE index_cursor
DEALLOCATE index_cursor
Установил fillfactor = 80% для часто изменяемых таблиц (документы). Это снижает фрагментацию при вставках новых записей.
Настроил оповещение, если фрагментация превышает 40% после ночного джоба (значит, что-то пошло не так).
"Спасибо! Теперь даже в последний день квартала 1С летает. А то раньше в пятницу после обеда можно было идти чай пить — пока документ проведется..."
— Главный бухгалтер, ООО "Ромашка"
⚠️ Важно:
Для файловой 1С (не SQL) процесс сложнее — нужно выгружать базу, запускать chdbfl.exe с ключом /I (переиндексация) или использовать обработку "Тестирование и исправление" с отключенными пользователями. Но принцип тот же: делать ночью, перед началом работы.