Настройки SQL для 1С: память, MAXDOP, tempdb

Дата: 07.10.2026 22:07:52
MS SQL Server
Производительность
Администрирование 1С
Клиент-сервер
Сервер 1С
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

Настройки SQL для 1С по умолчанию рассчитаны не на 1С: SQL Server забирает почти всю память, раскладывает короткие запросы платформы на несколько потоков, а файлы базы растут мелкими шагами. Всплывает это после переезда на MS SQL или новый сервер. Ниже — настройка MS SQL для 1С 8.3 на работающем сервере: аудит, конкретные значения, Shared Memory, приоритет процесса, обслуживание и проверка эффекта. Установка — в статье про установку MS SQL для 1С.

Почему MS SQL с настройками по умолчанию тормозит 1С

  • Память. max server memory по умолчанию не ограничена: SQL Server занимает почти всё ОЗУ, и рабочим процессам 1С (rphost) на той же машине памяти не хватает.
  • Параллелизм. MAXDOP = 0 отдаёт запросу все ядра: растут ожидания CXPACKET, а на ИТС описаны и взаимоблокировки параллельного плана с самим собой.
  • tempdb. Временные таблицы запросов (ПОМЕСТИТЬ) и сортировки, которым не хватило памяти, идут в tempdb; с одним файлом данных сеансы стоят в очереди к его служебным страницам.
  • Файлы и диски. Приращение по 1 МБ или 10% — частые паузы, FULL без копий журнала раздувает .ldf, а один диск на всё — общая очередь.

Настройки SQL для 1С: аудит работающего сервера

Скрипт только читает системные представления — запускайте в SSMS под администратором сервера, хоть в рабочее время. Нужен SQL Server 2016 SP2 или новее.

-- Аудит настроек MS SQL Server для 1С. Только чтение, ничего не меняет.
-- SSMS, подключение под администратором сервера. SQL Server 2016 SP2 и новее.

-- 1. Железо, редакция, Lock pages in memory, мгновенная инициализация файлов
SELECT CAST(SERVERPROPERTY('ProductVersion') AS nvarchar(32)) AS version,
       CAST(SERVERPROPERTY('Edition') AS nvarchar(128)) AS edition,
       i.cpu_count AS logical_cpu,
       i.physical_memory_kb / 1024 AS ram_mb,
       i.sql_memory_model_desc AS memory_model,        -- LOCK_PAGES: выдано право Lock pages in memory
       (SELECT TOP (1) s.instant_file_initialization_enabled
          FROM sys.dm_server_services AS s
         WHERE s.filename LIKE N'%sqlservr.exe%') AS ifi  -- Y: файлы данных растут без обнуления
FROM sys.dm_os_sys_info AS i;

-- 2. Параметры экземпляра: задано, действует и ориентир для 1С
SELECT c.name, c.value AS configured, c.value_in_use AS in_use, v.for_1c
FROM sys.configurations AS c
JOIN (VALUES (N'max server memory (MB)',         N'75% ОЗУ, не занятой 1С и другими программами'),
             (N'min server memory (MB)',         N'0; на виртуальной машине - разумный минимум'),
             (N'max degree of parallelism',      N'1 - методика 1С на ИТС'),
             (N'cost threshold for parallelism', N'при MAXDOP = 1 не используется; 50 - про запас'),
             (N'max worker threads',             N'0 - SQL Server считает сам'),
             (N'priority boost',                 N'0 - устаревшая опция')) AS v(name, for_1c)
  ON v.name = c.name COLLATE DATABASE_DEFAULT;

-- 3. tempdb: файлов данных по числу логических процессоров, но не больше 8, одного размера
SELECT type_desc, name, physical_name, size / 128 AS size_mb,
       IIF(is_percent_growth = 1, CONCAT(growth, N' %'), CONCAT(growth / 128, N' MB')) AS growth
FROM tempdb.sys.database_files;

-- 4. Файлы пользовательских баз: диск, размер, приращение (проценты и мелкие шаги - плохо)
SELECT DB_NAME(database_id) AS db, type_desc, name, physical_name, size / 128 AS size_mb,
       IIF(is_percent_growth = 1, CONCAT(growth, N' %'), CONCAT(growth / 128, N' MB')) AS growth,
       IIF(max_size IN (-1, 268435456), N'нет', CONCAT(max_size / 128, N' MB')) AS size_limit
FROM sys.master_files
WHERE database_id > 4
ORDER BY db, type_desc DESC;

-- 5. Параметры баз и число виртуальных журналов (VLF): сотни и тысячи - журнал рос мелкими шагами
SELECT d.name, d.recovery_model_desc, d.log_reuse_wait_desc,
       d.is_auto_create_stats_on, d.is_auto_update_stats_on,
       d.is_auto_shrink_on, d.is_auto_close_on,          -- оба должны быть 0
       d.page_verify_option_desc, d.compatibility_level, l.vlf_count
FROM sys.databases AS d
OUTER APPLY (SELECT COUNT(*) AS vlf_count FROM sys.dm_db_log_info(d.database_id)) AS l
WHERE d.database_id > 4 AND d.state = 0;

-- 6. Как подключен сервер 1С: Shared memory или TCP
SELECT s.program_name, s.host_name, c.net_transport, c.client_net_address, COUNT(*) AS sessions
FROM sys.dm_exec_sessions AS s
JOIN sys.dm_exec_connections AS c ON c.session_id = s.session_id
WHERE s.program_name LIKE N'1CV8%'
GROUP BY s.program_name, s.host_name, c.net_transport, c.client_net_address;

С чем сравнивать результат:

ПараметрПо умолчаниюДля 1С
max server memory (MB)2 147 483 64775% памяти, не занятой 1С и другими программами
max degree of parallelism0; мастер 2019+ предлагает своё — по числу процессоров и узлов NUMA1
cost threshold for parallelism5при MAXDOP = 1 не используется; про запас — 50
Файлы данных tempdbодин в старых версияхпо числу логических процессоров, не больше 8, одного размера
Приращение64 МБ с 2016; раньше 1 МБ и 10%данные 512–1024 МБ, журнал 256–512 МБ
Модель восстановлениякак у базы modelSIMPLE или FULL с копиями журнала

Память, MAXDOP и cost threshold

Microsoft советует начинать max server memory с 75% памяти, не занятой другими процессами. Если сервер 1С на той же машине, сначала вычтите память rphost, замеренную в час пик: фиксированные нормы «на процесс» из старых инструкций не годятся. Скрипт только считает:

# Только чтение. Ориентир для max server memory и проверка сервера, где стоит SQL Server.
# PowerShell от имени администратора, в час пик: рабочие процессы 1С уже набрали память.
$ramMb  = [math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1MB)
$rphost = @(Get-Process rphost -ErrorAction SilentlyContinue)
$onecMb = 0
if ($rphost.Count -gt 0) {
    # Память рабочих процессов 1С сейчас плюс 30% запаса на рост
    $onecMb = [math]::Round(($rphost | Measure-Object WorkingSet64 -Sum).Sum / 1MB * 1.3)
}
$sqlMb = [math]::Round(($ramMb - $onecMb) * 0.75)   # 75% памяти, не занятой другими процессами
"ОЗУ: $ramMb МБ; rphost: $($rphost.Count) шт., с запасом $onecMb МБ"
"Ориентир max server memory: $sqlMb МБ"

# Приоритет процесса SQL Server: Normal по умолчанию, High после .reg из статьи
Get-Process sqlservr -ErrorAction SilentlyContinue | Select-Object Id, PriorityClass

# Схема электропитания: для сервера СУБД - «Высокая производительность»
powercfg /getactivescheme

# Тома: файловая система и размер кластера (под файлы SQL Server обычно 65536 = 64 КБ)
Get-Volume | Where-Object DriveLetter |
    Select-Object DriveLetter, FileSystemLabel, FileSystem, AllocationUnitSize,
        @{ Name = 'FreeGB'; Expression = { [math]::Round($_.SizeRemaining / 1GB) } }

В Standard буферный пул ограничен 128 ГБ (SQL Server 2022) — память сверх этого полезнее отдать 1С. На выделенном сервере 75% — стартовая точка: если ОЗУ остаётся свободным, лимит поднимают ступенями. Применяем:

-- Применение настроек SQL для 1С. Перед запуском - свежая резервная копия.
-- Числа - пример: 128 ГБ ОЗУ, 16 логических процессоров, сервер 1С на другой машине.

-- 1. Память и параллелизм: действуют сразу после RECONFIGURE, без перезапуска
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'max server memory (MB)', 98304;        -- в мегабайтах: 75% от 128 ГБ
EXEC sp_configure 'max degree of parallelism', 1;         -- методика 1С на ИТС
EXEC sp_configure 'cost threshold for parallelism', 50;   -- на случай, если MAXDOP поднимут
RECONFIGURE;

-- 2. tempdb: выровнять размер и приращение, добавить файлы до 8. Скрипт только печатает команды,
--    размер берется по самому большому файлу данных
DECLARE @files int = 8, @dir nvarchar(260) = N'T:\TempDB\', @sql nvarchar(max) = N'';
DECLARE @size int = (SELECT MAX(size) / 128 FROM tempdb.sys.database_files WHERE type_desc = N'ROWS');
DECLARE @n int = (SELECT COUNT(*) FROM tempdb.sys.database_files WHERE type_desc = N'ROWS');
SELECT @sql += CONCAT(N'ALTER DATABASE tempdb MODIFY FILE (NAME = ', QUOTENAME(name, ''''),
                      IIF(size / 128 < @size, CONCAT(N', SIZE = ', @size, N'MB'), N''),
                      N', FILEGROWTH = 512MB);', NCHAR(10))
FROM tempdb.sys.database_files WHERE type_desc = N'ROWS';
WHILE @n < @files
BEGIN
    SET @n += 1;
    SET @sql += CONCAT(N'ALTER DATABASE tempdb ADD FILE (NAME = N''temp', @n, N''', FILENAME = N''',
                       @dir, N'temp', @n, N'.ndf'', SIZE = ', @size, N'MB, FILEGROWTH = 512MB);', NCHAR(10));
END;
PRINT @sql;   -- проверьте путь @dir и число файлов, затем выполните напечатанное

-- 3. Приращение файлов базы trade фиксированными шагами: тоже печатает команды
SELECT CONCAT(N'ALTER DATABASE ', QUOTENAME(DB_NAME(database_id)), N' MODIFY FILE (NAME = ',
              QUOTENAME(name, ''''), N', FILEGROWTH = ', IIF(type_desc = N'LOG', N'512MB', N'1024MB'), N');') AS command
FROM sys.master_files
WHERE database_id = DB_ID(N'trade');

-- 4. Параметры базы. RECOVERY SIMPLE - только если хватает ночной полной копии:
--    переход рвет цепочку копий журнала, при возврате в FULL сразу делают полную копию
ALTER DATABASE trade SET AUTO_SHRINK OFF;
-- ALTER DATABASE trade SET RECOVERY SIMPLE;

MAXDOP = 1 — рекомендация 1С на ИТС. cost threshold for parallelism — стоимость плана, с которой оптимизатор рассматривает параллельный вариант; при MAXDOP = 1 не используется, но пригодится, если MAXDOP поднимут ради отчётов (5 по умолчанию Microsoft называет отправной точкой, а не рекомендацией). Старые советы «Поддерживать приоритет SQL Server» (priority boost) и max worker threads = 2048 не применяйте: первый устарел и отнимает процессор у ОС и сети, для второго правильное значение 0.

tempdb, приращение файлов и диски

Файлов данных tempdb — по числу логических процессоров, но не больше восьми; если ожидания PAGELATCH на tempdb остаются, добавляют по четыре. Размер и приращение одинаковые: SQL Server заполняет файлы пропорционально свободному месту, и большой файл соберёт основную нагрузку. Ровно новые файлы заработают после перезапуска службы — tempdb пересоздаётся при каждом запуске.

Чтобы рост файла данных не останавливал работу, учётной записи службы SQL Server дают право «Выполнение задач по обслуживанию томов» (secpol.msc), в аудите — ifi = Y. Журнал при росте обнуляется (с SQL Server 2022 — кроме приращений до 64 МБ), его сразу делают нужного размера. Данные, журнал и tempdb — на разных SSD-томах с кластером 64 КБ, tempdb — на самом быстром; каталоги с .mdf, .ndf и .ldf исключают из проверки антивирусом.

Модель восстановления: хватает ночной полной копии — SIMPLE; нужно восстановление на момент времени — FULL и регулярный BACKUP LOG, иначе журнал займёт диск (см. о переполненном журнале транзакций). Ограничивать размер журнала, как советуют старые инструкции, не нужно: крупное проведение упрётся в лимит.

Shared Memory: сервер 1С и MS SQL на одной машине

Если rphost и SQL Server на одном компьютере, соединение через общую память обходится без сетевого стека; выигрыш заметнее на операциях с множеством коротких обращений к СУБД. Блок 6 аудита показывает протокол: нужно net_transport = Shared memory. Если там TCP:

  1. SQL Server Configuration Manager → SQL Server Network Configuration → Protocols for MSSQLSERVER: Shared Memory включён (по умолчанию — да; изменения действуют после перезапуска службы).
  2. Консоль «Администрирование серверов 1С:Предприятия» → кластер → «Информационные базы» → свойства базы → «Сервер баз данных»: вместо srv01 или IP-адреса укажите lpc:srv01.
  3. В окно обслуживания перезапустите службу сервера 1С и повторите блок 6.

Префикс lpc: работает только на той же машине: при переносе SQL Server на другой сервер его убирают. С IP-адресом в поле клиент идёт по TCP даже локально.

Приоритет sqlservr.exe: .reg из практики

Из практики: высокий приоритет процессу SQL Server задают через раздел реестра Image File Execution Options — Windows применяет его при каждом запуске sqlservr.exe.

Windows Registry Editor Version 5.00

; sqlservr_high.reg - высокий приоритет процессу SQL Server (из практики).
; Действует на все процессы sqlservr.exe на этой машине со следующего запуска службы.
; CpuPriorityClass: 2 - обычный (Normal), 3 - высокий (High).
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sqlservr.exe\PerfOptions]
"CpuPriorityClass"=dword:00000003

Откат удаляет только подраздел PerfOptions:

Windows Registry Editor Version 5.00

; sqlservr_normal.reg - откат: удаляет только подраздел PerfOptions, остальное не трогает.
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sqlservr.exe\PerfOptions]

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

rem cmd от имени администратора на сервере СУБД, в окно обслуживания. Каталог C:\Backup должен существовать.
rem 1. Копия раздела. Если reg export ответит ошибкой, раздела не было - откатывать нечего
reg export "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sqlservr.exe" C:\Backup\ifeo_sqlservr.reg /y
rem 2. Применение и перезапуск экземпляра по умолчанию (у именованного - MSSQL$ИМЯ и SQLAgent$ИМЯ)
reg import sqlservr_high.reg
net stop MSSQLSERVER /y
net start MSSQLSERVER
net start SQLSERVERAGENT
rem 3. Проверка - PowerShell-скрипт из раздела про память: у sqlservr должно быть PriorityClass = High

Оговорки:

  • PerfOptions в документации Microsoft не описан, значения известны по ответам на её форуме — проверяйте результат PowerShell-командой выше.
  • По сути это то же, что устаревший priority boost: при загрузке процессора под 100% SQL Server отнимет время у Windows, rphost и пользователей терминального сервера.
  • На незагруженном процессоре приоритет ничего не даёт, а тяжёлые запросы не ускоряет.
  • Действует на все экземпляры на машине; антивирусы и EDR следят за этим разделом — предупредите безопасников.

Применяйте последним, после памяти, MAXDOP и tempdb, с замером до и после.

Обслуживание: статистика и индексы

Методика 1С на ИТС: регулярно обновлять статистику и сразу после неё очищать процедурный кэш, дефрагментировать и перестраивать индексы; по практике статистику — ежедневно, индексы — раз в неделю. Автообновление статистики на больших таблицах 1С срабатывает с запозданием, и планы строятся по устаревшей статистике. Шаги для задания SQL Server Agent (в Express агента нет — sqlcmd из планировщика Windows):

-- Обслуживание базы trade: шаги задания SQL Server Agent. Ночью, вне регламентных
-- заданий 1С, обменов и резервного копирования.
USE trade;

-- Шаг 1, ежедневно. Статистика: sp_updatestats обновляет только ту, где менялись строки
EXEC sp_updatestats;

-- Шаг 2, сразу после шага 1. Методика ИТС: после статистики очистить кэш планов.
-- DBCC FREEPROCCACHE чистит кэш всего экземпляра, эта команда (2016+) - только текущей базы
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;

-- Шаг 3, раз в неделю. Индексы: REORGANIZE при 10-30% фрагментации, REBUILD - выше 30%
-- (и всегда REBUILD, если запрещены блокировки страниц - у 1С так с 8.3.22: REORGANIZE там не работает)
DECLARE @sql nvarchar(max) = N'';
SELECT @sql += CONCAT(N'ALTER INDEX ', QUOTENAME(i.name), N' ON ', QUOTENAME(s.name), N'.', QUOTENAME(o.name),
                      IIF(ps.avg_fragmentation_in_percent >= 30 OR i.allow_page_locks = 0,
                          N' REBUILD WITH (SORT_IN_TEMPDB = ON);', N' REORGANIZE;'),
                      NCHAR(10))
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ps
JOIN sys.indexes AS i ON i.object_id = ps.object_id AND i.index_id = ps.index_id
JOIN sys.objects AS o ON o.object_id = ps.object_id
JOIN sys.schemas AS s ON s.schema_id = o.schema_id
WHERE ps.index_id > 0                          -- кучи без кластерного индекса пропускаем
  AND ps.alloc_unit_type_desc = N'IN_ROW_DATA' -- одна строка на индекс
  AND ps.page_count >= 1000                    -- маленькие индексы перестраивать незачем
  AND ps.avg_fragmentation_in_percent >= 10
  AND i.is_disabled = 0
  AND o.is_ms_shipped = 0;
PRINT @sql;                                    -- в журнал шага попадут первые 4000 символов
EXEC sp_executesql @sql;

Пороги 10% и 30% — ориентир, а не закон. С 8.3.22 у индексов 1С запрещены блокировки страниц, поэтому скрипт их только перестраивает; ИТС для REORGANIZE советует на время включать ALLOW_PAGE_LOCKS. В Standard нет онлайн-перестроения и параллельного обслуживания индексов: REBUILD держит таблицу до конца, поэтому только ночью и не вместе с регламентными заданиями 1С.

Как проверить эффект

Скрипт снимает счётчики ожиданий и дисков, ждёт 15 минут и показывает разницу. Запустите его до изменений и через день после — в тот же час, при похожей нагрузке.

-- Проверка эффекта: что сервер ждал и как отвечали диски за 15 минут рабочей нагрузки.
-- Только чтение. Запускайте до изменений и после, в один и тот же час рабочего дня.
DECLARE @delay char(8) = CONVERT(char(8), DATEADD(MINUTE, 15, 0), 108);   -- '00:15:00'

SELECT wait_type, waiting_tasks_count, wait_time_ms, signal_wait_time_ms
INTO #w0 FROM sys.dm_os_wait_stats;
SELECT database_id, file_id, num_of_reads, io_stall_read_ms, num_of_writes, io_stall_write_ms
INTO #f0 FROM sys.dm_io_virtual_file_stats(NULL, NULL);

WAITFOR DELAY @delay;

-- 1. Десять главных ожиданий за интервал, без фоновых «спящих» типов
SELECT TOP (10) w.wait_type,
       w.wait_time_ms - w0.wait_time_ms AS wait_ms,
       w.waiting_tasks_count - w0.waiting_tasks_count AS waits,
       w.signal_wait_time_ms - w0.signal_wait_time_ms AS signal_ms   -- ожидание процессора
FROM sys.dm_os_wait_stats AS w
JOIN #w0 AS w0 ON w0.wait_type = w.wait_type
WHERE w.wait_time_ms > w0.wait_time_ms
  AND w.wait_type NOT LIKE N'%SLEEP%' AND w.wait_type NOT LIKE N'%QUEUE%'
  AND w.wait_type NOT LIKE N'XE%' AND w.wait_type NOT LIKE N'BROKER%'
  AND w.wait_type NOT LIKE N'SQLTRACE%' AND w.wait_type NOT LIKE N'HADR%'
  AND w.wait_type NOT IN (N'WAITFOR', N'REQUEST_FOR_DEADLOCK_SEARCH', N'DIRTY_PAGE_POLL',
                          N'SOS_WORK_DISPATCHER', N'FT_IFTS_SCHEDULER_IDLE_WAIT')
ORDER BY wait_ms DESC;

-- 2. Средняя задержка чтения и записи по файлам за интервал, мс
SELECT DB_NAME(f.database_id) AS db, m.type_desc, m.physical_name,
       f.num_of_reads - f0.num_of_reads AS reads,
       (f.io_stall_read_ms - f0.io_stall_read_ms) / NULLIF(f.num_of_reads - f0.num_of_reads, 0) AS avg_read_ms,
       f.num_of_writes - f0.num_of_writes AS writes,
       (f.io_stall_write_ms - f0.io_stall_write_ms) / NULLIF(f.num_of_writes - f0.num_of_writes, 0) AS avg_write_ms
FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS f
JOIN #f0 AS f0 ON f0.database_id = f.database_id AND f0.file_id = f.file_id
JOIN sys.master_files AS m ON m.database_id = f.database_id AND m.file_id = f.file_id
ORDER BY avg_read_ms DESC;

-- 3. Сколько секунд страница живет в кэше: смотрите динамику, а не порог
SELECT cntr_value AS page_life_expectancy_sec
FROM sys.dm_os_performance_counters
WHERE object_name LIKE N'%Buffer Manager%' AND counter_name = N'Page life expectancy';

DROP TABLE #w0, #f0;
  • CXPACKET, CXCONSUMER — параллельные планы, после MAXDOP = 1 почти исчезают.
  • PAGEIOLATCH_* — чтение с диска: мало памяти или медленный диск, Page life expectancy падает.
  • WRITELOG — медленный диск журнала.
  • PAGELATCH_* на tempdb — мало файлов.
  • LCK_M_* — блокировки, это уже код 1С: см. конфликт блокировок.
  • SOS_SCHEDULER_YIELD, большая доля signal_ms — не хватает процессора.
  • ASYNC_NETWORK_IO — сервер 1С не успевает забирать результат.

Задержка дисков на SSD — единицы миллисекунд (ориентир из практики); десятки — диск не успевает, параметрами SQL Server это не лечится.

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

// Модуль формы внешней обработки «Замер запросов до и после настройки SQL».
// По каждому регистру накопления два запроса: таблица движений и виртуальная таблица
// остатков или оборотов. Итог - в сообщении и в журнале регистрации (событие «Замер SQL»).

&НаКлиенте
Процедура ЗамеритьЗапросы(Команда)

	// Пусто - все регистры накопления. В УТ 11.4 и КА 2.5 есть, например, эти:
	ИменаРегистров = "ТоварыНаСкладах,ТоварыОрганизаций,ВыручкаИСебестоимостьПродаж";
	Сообщить(ЗамеритьРегистрыНакопления(ИменаРегистров, 3));

КонецПроцедуры

// Возвращает текст отчета: регистр, число записей, медиана времени из Повторов прогонов, мс
&НаСервереБезКонтекста
Функция ЗамеритьРегистрыНакопления(Знач ИменаРегистров, Знач Повторов)

	Регистры = Новый Массив;
	Если ПустаяСтрока(ИменаРегистров) Тогда
		Для Каждого Регистр Из Метаданные.РегистрыНакопления Цикл
			Регистры.Добавить(Регистр);
		КонецЦикла;
	Иначе
		Для Каждого ИмяРегистра Из СтрРазделить(ИменаРегистров, ",", Ложь) Цикл
			Регистр = Метаданные.РегистрыНакопления.Найти(СокрЛП(ИмяРегистра));
			Если Регистр <> Неопределено Тогда
				Регистры.Добавить(Регистр);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;

	Строки = Новый Массив;
	Строки.Добавить(СтрШаблон("Замер %1, повторов: %2", Формат(ТекущаяДатаСеанса(), "ДЛФ=DT"), Повторов));
	ТекстСчетчика = "ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Записей ИЗ РегистрНакопления.";
	Для Каждого Регистр Из Регистры Цикл
		Если Регистр.ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда
			Таблица = "Остатки";
		Иначе
			Таблица = "Обороты";
		КонецЕсли;
		Попытка
			Движения = ЗамерЗапроса(ТекстСчетчика + Регистр.Имя, Повторов);
			Итоги = ЗамерЗапроса(ТекстСчетчика + Регистр.Имя + "." + Таблица + "()", Повторов);
			Строки.Добавить(СтрШаблон("%1: движений %2 - %3 мс; %4() - %5 мс", Регистр.Имя,
				Формат(Движения.Записей, "ЧН=0; ЧГ=0"), Формат(Движения.Медиана, "ЧН=0; ЧГ=0"),
				Таблица, Формат(Итоги.Медиана, "ЧН=0; ЧГ=0")));
		Исключение
			Строки.Добавить(Регистр.Имя + ": " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецПопытки;
	КонецЦикла;

	Отчет = СтрСоединить(Строки, Символы.ПС);
	ЗаписьЖурналаРегистрации("Замер SQL", УровеньЖурналаРегистрации.Информация, , , Отчет);
	Возврат Отчет;

КонецФункции

// Выполняет запрос Повторов раз, возвращает число записей и медиану времени, мс.
// Первый прогон после перезапуска SQL Server медленнее: данные читаются с диска
&НаСервереБезКонтекста
Функция ЗамерЗапроса(Знач ТекстЗапроса, Знач Повторов)

	Запрос = Новый Запрос(ТекстЗапроса);
	Времена = Новый СписокЗначений;
	Записей = 0;
	Для Номер = 1 По Макс(Повторов, 1) Цикл
		Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
		Выборка = Запрос.Выполнить().Выбрать();
		Если Выборка.Следующий() Тогда
			Записей = Выборка.Записей;
		КонецЕсли;
		Времена.Добавить(ТекущаяУниверсальнаяДатаВМиллисекундах() - Начало);
	КонецЦикла;

	// Медиана устойчивее среднего к разовым всплескам нагрузки
	Времена.СортироватьПоЗначению();
	Медиана = Времена.Получить(Цел(Времена.Количество() / 2)).Значение;
	Возврат Новый Структура("Записей, Медиана", Записей, Медиана);

КонецФункции

Первый прогон после перезапуска SQL Server медленнее — данные ещё не в памяти, поэтому берётся медиана. На большой базе хватит 3–5 ключевых регистров.

Разбор ключевых строк

  • c.value и c.value_in_use — заданное и действующее значение; разные — забыли RECONFIGURE, а у priority boost — не перезапустили службу; min server memory 0 при in_use 16 — норма.
  • COLLATE DATABASE_DEFAULT — у системных представлений своя сортировка, без него возможен конфликт сортировок.
  • LIKE N'1CV8%' — сеансы сервера 1С, net_transport показывает их протокол.
  • CLEAR PROCEDURE_CACHE — кэш планов только текущей базы, остальные базы не страдают.
  • N'IN_ROW_DATA' — строка на индекс: для таблиц со строками неограниченной длины функция возвращает ещё и LOB-страницы.
  • ВидРегистраНакопления.Остатки — для регистров остатков читаем Остатки(), для оборотных — Обороты().

Типичные ошибки

  • «The configuration option 'max degree of parallelism' does not exist, or it may be an advanced option.» Сначала sp_configure 'show advanced options', 1 и RECONFIGURE.
  • «MODIFY FILE failed. Specified size is less than or equal to current size.» MODIFY FILE только увеличивает файл; уменьшают DBCC SHRINKFILE.
  • «Intra-query parallelism caused your server command (process ID #…) to deadlock…» MAXDOP не равен 1.
  • «There is insufficient system memory in resource pool 'default' to run this query.» Лимит памяти слишком мал — например, ввели гигабайты вместо мегабайт.
  • «The transaction log for database 'trade' is full due to…» Журналу ограничили размер или база в FULL без копий журнала.
  • 1С не подключается к СУБД после переноса SQL Server. В параметрах базы остался префикс lpc:.

Частые вопросы

Нужно ли перезапускать SQL Server после изменения настроек?

Для памяти, MAXDOP и cost threshold — нет, они действуют после RECONFIGURE. Перезапуск нужен для ровных файлов tempdb, сетевых протоколов, права на обслуживание томов и приоритета из .reg.

Сколько памяти оставить 1С, если всё на одном сервере?

Столько, сколько rphost занимают в пик, с запасом, — PowerShell-скрипт считает это сам. Если после ограничения растут ожидания PAGEIOLATCH, памяти мало обоим: добавляйте ОЗУ или выносите СУБД на отдельный сервер.

Не замедлит ли MAXDOP = 1 тяжёлые отчёты и обслуживание?

Отдельный запрос может стать медленнее — его ускоряют индексами и переписыванием, а не параллелизмом на весь сервер. В Enterprise MAXDOP можно указать в самой команде ALTER INDEX — на время операции он перекрывает серверную настройку.

Отличается ли настройка MS SQL 2022 для 1С?

Параметры те же. Мастер 2022 сам предлагает MAXDOP и лимит памяти, а платформа поддерживает SQL Server 2022 с версии 8.3.22. Что стоит на самом деле — покажет аудит.

Когда проще заказать

Оптимизация MS SQL для 1С заканчивается там, где начинаются запросы, блокировки и код конфигурации: если аудит чистый, а 1С тормозит, нужна диагностика программиста. Опишите симптомы в услуге «1С тормозит» или разместите задачу: оценка бесплатная, ответ в течение рабочего дня.

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.