В этот краткий сборник рецептов входят советы, применимые к подавляющему большинству развертываний SQL Server без профилирования реальной нагрузки.

Используйте привилегию «Lock Pages In memory»

Откройте оснастку «Local Security Policy». В параметре «Local Policies — User Right Assignment — Lock pages In memory» задайте учетные записи под которыми запускаются все используемые инстансы.

Подробнее

Плохо:

Хорошо:

Это позволит избежать вытеснения страниц буферного пула в своп.

Используйте привилегию «Perform Volume Maintenance Tasks»

Откройте оснастку Local Security Policy. В параметре Local Policies — User Right Assignment — Perform Volume Maintenance Tasks задайте учетные записи всех используемых инстансов. Начиная с SQL Server 2016 эту привилегию предложит добавить инсталлятор.

Скрытый текст

Хорошо:

Это позволит мгновенно расширять файлы данных баз.

Настройте файловую систему

Используйте выделенные тома для баз данных и журналов транзакций. Форматируйте диск в NTFS с кластером 64k. Это соответствует размеру экстента SQL и позволит снизить число операций ввода вывода, что особенно важно для фрагментированных данных на HDD. При создании RAID массива на СХД так же учитывайте эту особенность.

Скрытый текст

Хорошо:

Плохо:

Это позволит кратно снизить обращения к файловой системе — читать не 16 кластеров по 4Kb, а один на 64Kb.

Настройте tempdb

Расположите tempdb на самом быстром хранилище. Это высоконагруженная база данных, которую использует как сам SQL Server, так и все другие базы данных. Разбивайте tempdb на несколько файлов. Создайте по одному файлу на каждое ядро, разумный максимум — 8 файлов. Укажите для каждого файла одинаковый изначальный размер и одинаковый размер увеличения в мегабайтах. Размер файлов зависит от фактической потребности и может быть достаточно небольшим.

Скрытый текст

Это позволит снизить конкуренцию за tempdb

Ограничьте Max Server Memory

Снизьте максимальный объем буферного пула, оставив операционной системе и другим компонентам SQL Server разумное количество памяти (6–8Gb).

Скрытый текст

Судя по Unused, на этом сервере памяти с избытком. Прибавка MAX_MEMORY не меняет картину — базы данных маленькие с небольшой нагрузкой.

Это позволит избежать чрезмерного своппинга.

Ограничьте параллелизм запросов

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

Установите "Cost Threshold for Parallelism" = 50.
Отправной точкой для выбора значения MAXDOP можно считать половину установленных ядер. Увеличение значения должно быть обосновано характером нагрузки на базу, руководствуйтесь статьей вендора.

Опытные DBA скептически относятся к высоким значениям MAXDOP, и рекомендуют ограничиться значением от 4 до 6, разумным максимумом является 8. Большое спасибо за комментарии @wadegи @Tzimie.

рекомендует вовсе отказаться от разбиения запросов и установить MAXDOP=1.

Это позволит разбивать на части ограниченное число действительно продолжительных запросов.

Задайте достаточный размер журнала транзакций

На журнал транзакций не действует Instant File Initialization, он всегда зануляется (исключение - SQL Server 2022 при размере прироста не более 64Mb, спасибо @katamoto).

Для расширения используйте Auto Grow с шагом 1–4Gb. Для больших баз данных эта цифра может быть значительно выше. Никогда не ограничивайте полный размер журнала транзакций.

Скрытый текст

Если вы ограничите размер журнала транзакций, то когда он полностью заполнится, вы окажетесь в затруднительной ситуации. Для того, чтобы его увеличить необходимо выполнить ALTER DATABASE, а места для этой транзакции в журнале нет. Придется его освобождать, выполнив BACKUP LOG.

Это позволит снизить задержки, связанные с выделением места для роста журнала транзакций.

Оптимизируйте индексы

Используйте скрипты Ola Hallergen для создания ежедневных заданий оптимизации и перестроения индексов.

Это позволит поддерживать базу данных в тонусе и существенно повысить скорость выполнения запросов.

Обратите внимание на настройку Optimize for Ad Hoc Workloads

Включение этой настройки потенциально экономит расход памяти кеша запросов. Универсального совета нет, чтобы оценить выгоду, необходима статистика реальной нагрузки.

В качестве примера можно руководствоваться этой статьёй.

Скрытый текст

По мнению автора статьи, цифра в 25% - порог для включения настройки.

SELECT AdHoc_Plan_MB, Total_Cache_MB,
AdHoc_Plan_MB*100.0 / Total_Cache_MB AS 'AdHoc %'
FROM (
SELECT SUM(CASE
WHEN objtype = 'adhoc'
THEN convert(float,size_in_bytes)
ELSE 0 END) / 1048576.0 AdHoc_Plan_MB,
SUM(convert(float,size_in_bytes)) / 1048576.0 Total_Cache_MB
FROM sys.dm_exec_cached_plans) T

И немного нейрослопа. По мнению ChatGPT, включение настройки позволит сэкономить объем памяти, выводимой в третьей колонке

SELECT
    SUM(CONVERT(bigint, size_in_bytes)) / 1048576.0 AS Total_Cache_MB,

    SUM(CASE
        WHEN objtype = 'Adhoc'
        THEN CONVERT(bigint, size_in_bytes)
        ELSE 0
    END) / 1048576.0 AS AdHoc_MB,

    SUM(CASE
        WHEN objtype = 'Adhoc' AND usecounts = 1
        THEN CONVERT(bigint, size_in_bytes)
        ELSE 0
    END) / 1048576.0 AS AdHoc_1use_MB
FROM sys.dm_exec_cached_plans;

Используйте Activity Monitor

Изучите колонку «Ожидания» в мониторе активности и разберитесь, что является узким местом.

Это позволит не действовать наугад.

Повышайте когнитивные функции

Прочитайте книгу Дмитрия Короткевича «SQL Server. Наладка и оптимизация для профессионалов»

Это позволит продолжить тонкую оптимизацию сервера для вашей базы данных

PS: Я не DBA, критика приветствуется.

Комментарии (15)


  1. katamoto
    10.09.2026 09:21

    Если на журнал транзакций не действует Instant File Initialization, то зачем ему ставить прирост с шагом 1–4Gb? Тем более, что с MSSQL 2022 IFI распростанятеся и на лог (но только если прирост не больше 64 MB)


    1. gotch Автор
      10.09.2026 09:21

      Задача его инициализировать сразу нормального размера. Но мы знаем, что жизнь всегда богаче, и вырасти он может. На сколько прибавлять? И тут понеслись компромиссы. Прибавить 10Gb - это задержка на зануление. Прибавить 100Mb - избыточное число VLF. Сам обычно ставил примерно одну десятую от целевого размера файла, но Короткевич приводит цифру 1-4Gb. Кто я что бы спорить с экспертом.

      О MS SQL 2022 нам только мечтать, спасибо за информацию. Могу еще несколько trace флагов для 2008 написать, вот реальность нашей жизни.


      1. katamoto
        10.09.2026 09:21

        Насколько вообще количество VLF реально влияет на производительность? Какой-то оверхед, несомненно, есть, но насколько он значим на современном железе? Может это уже как те пресловутые рекомендации о 5% и 30% для реогра\ребилда, которые тянутся из глубины веков и не сильно релевантны для реалий NVME дисков?


        1. gotch Автор
          10.09.2026 09:21

          Это, к сожалению, вопрос не моего уровня. На NVME и кластер файловой системы можно любой делать, ему до фрагментации дела нет, а здесь много баз на обычном железе, они еле дышат, хоть чем-то помочь.


  1. wadeg
    10.09.2026 09:21

    Установите MAXDOP равным половине доступных ядер...

    ...и получите постоянные взаимоблокировки внутри одного (!) запроса в подарок. Практический беспроблемный максимум - 6...8, не более.


    1. gotch Автор
      10.09.2026 09:21

      Значение по-умолчанию в этом случае работает лучше?


      1. wadeg
        10.09.2026 09:21

        Так же отвратительно, как и ваша половина ядер.


        1. gotch Автор
          10.09.2026 09:21

          Значит, например, на сервере с 24 ядрами и max dop 12 и ценой в 50 блокировки гарантированы?


          1. wadeg
            10.09.2026 09:21

            Не понимаю, про какую цену речь, а на сервере с 24 ядрами и maxdop=12 регулярные дурные блокировки на многопоточных запросах будут возникать регулярно.

            UPD: добавлю, что в свежих релизах это так и ниасилено. Все, что MS родили - чуть больше диагностики добавили в 2016sp2 (см. тут п.19). Объяснения примерно такие. И да, не видел буквально ни одной инсталляции без хорошего ограничения maxdop, где бы это не стреляло постоянно.


            1. Tzimie
              10.09.2026 09:21

              При парралелизме взаимоблокировки в рамках одного spid это не блокировки вообще, а координация процессов (главный ждёт подчинённых ). Я обычно ставлю 4 чтобы тяжёлый scan не скушал очень много


              1. wadeg
                10.09.2026 09:21

                Именно взаимоблокировки, с соответсвующей записью в логе. Причина, видимо, обычно как раз указанная вами (и приводимая тут самой ms), но, похоже, и они сами в этом не слишком уверены. Так что это не просто "чтобы не скушал много" - это бы лвдно, если ядер с запасом, но это вынужденная мера против внутрипроцессных клинчей со всеми вытекающими.


              1. gotch Автор
                10.09.2026 09:21

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


            1. gotch Автор
              10.09.2026 09:21

              Я не то чтобы настаиваю на такой формулировке, и с удовольствием поменяю её на другое число, если более опытные товарищи могут дать разумную, обоснованную рекомендацию. Подход по этой ссылке вы считаете разумным?
              https://learn.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-max-degree-of-parallelism-server-configuration-option?view=sql-server-ver17


              1. wadeg
                10.09.2026 09:21

                С той частью, где говорится про 8, согласен, но 6 железно без проблем. 16 - нет, конечно, уже железно будут блокироваться.


                1. gotch Автор
                  10.09.2026 09:21

                  Спасибо, исправил.