Настройки SQL для 1С по умолчанию рассчитаны не на 1С: SQL Server забирает почти всю память, раскладывает короткие запросы платформы на несколько потоков, а файлы базы растут мелкими шагами. Всплывает это после переезда на MS SQL или новый сервер. Ниже — настройка MS SQL для 1С 8.3 на работающем сервере: аудит, конкретные значения, Shared Memory, приоритет процесса, обслуживание и проверка эффекта. Установка — в статье про установку MS 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 647 | 75% памяти, не занятой 1С и другими программами |
| max degree of parallelism | 0; мастер 2019+ предлагает своё — по числу процессоров и узлов NUMA | 1 |
| cost threshold for parallelism | 5 | при MAXDOP = 1 не используется; про запас — 50 |
| Файлы данных tempdb | один в старых версиях | по числу логических процессоров, не больше 8, одного размера |
| Приращение | 64 МБ с 2016; раньше 1 МБ и 10% | данные 512–1024 МБ, журнал 256–512 МБ |
| Модель восстановления | как у базы model | SIMPLE или FULL с копиями журнала |
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 — по числу логических процессоров, но не больше восьми; если ожидания 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, иначе журнал займёт диск (см. о переполненном журнале транзакций). Ограничивать размер журнала, как советуют старые инструкции, не нужно: крупное проведение упрётся в лимит.
Если rphost и SQL Server на одном компьютере, соединение через общую память обходится без сетевого стека; выигрыш заметнее на операциях с множеством коротких обращений к СУБД. Блок 6 аудита показывает протокол: нужно net_transport = Shared memory. Если там TCP:
srv01 или IP-адреса укажите lpc:srv01.Префикс lpc: работает только на той же машине: при переносе SQL Server на другой сервер его убирают. С IP-адресом в поле клиент идёт по TCP даже локально.
Из практики: высокий приоритет процессу 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
Оговорки:
Применяйте последним, после памяти, 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;
Задержка дисков на 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-страницы.ВидРегистраНакопления.Остатки — для регистров остатков читаем Остатки(), для оборотных — Обороты().sp_configure 'show advanced options', 1 и RECONFIGURE.lpc:.Для памяти, MAXDOP и cost threshold — нет, они действуют после RECONFIGURE. Перезапуск нужен для ровных файлов tempdb, сетевых протоколов, права на обслуживание томов и приоритета из .reg.
Столько, сколько rphost занимают в пик, с запасом, — PowerShell-скрипт считает это сам. Если после ограничения растут ожидания PAGEIOLATCH, памяти мало обоим: добавляйте ОЗУ или выносите СУБД на отдельный сервер.
Отдельный запрос может стать медленнее — его ускоряют индексами и переписыванием, а не параллелизмом на весь сервер. В Enterprise MAXDOP можно указать в самой команде ALTER INDEX — на время операции он перекрывает серверную настройку.
Параметры те же. Мастер 2022 сам предлагает MAXDOP и лимит памяти, а платформа поддерживает SQL Server 2022 с версии 8.3.22. Что стоит на самом деле — покажет аудит.
Оптимизация MS SQL для 1С заканчивается там, где начинаются запросы, блокировки и код конфигурации: если аудит чистый, а 1С тормозит, нужна диагностика программиста. Опишите симптомы в услуге «1С тормозит» или разместите задачу: оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.