
СОДЕРЖАНИЕ:
1. Оптимизация SQL-запросов
2. Настройка сервера с нуля
3. Конфигурация новой базы данных
4. Перенастройка действующей базы
5. Распределение по RAID-массивам
6.Стратегия размещения на SSD
7. Правила настройки дисков и ОС
8. Перенос существующих баз
9. Версии SQL Server: память и объёмы
1. Оптимизация SQL-запросов:
По данным практики большинства DBA, до 70–80% проблем производительности решаются оптимизацией запросов и индексов - ещё до настройки железа или конфигурации сервера.




Ключевые правила написания запросов - избегайте SELECT *, функций над индексируемыми столбцами в WHERE, неявных преобразований типов и курсоров там, где достаточно одного set-based запроса.
| Антипаттерн | Проблема | Решение |
| WHERE YEAR(date) = 2024 | Функция блокирует использование индекса | WHERE date >= '2024-01-01' AND date < '2025-01-01' |
| SELECT * FROM Orders | Лишние столбцы - лишний I/O | Перечислить только нужные столбцы |
| LIKE '%text%' | Full scan, индекс игнорируется | Full-Text Search или начальный LIKE 'text%' |
| N+1 запросы (курсоры) | Тысячи round-trip к серверу | JOIN или одна процедура с temp table |
| Неявное приведение типов | Implicit convert - scan вместо seek | Явное CAST/CONVERT или приведение схемы |
| Нет покрывающего индекса | Key Lookup = +1 операция на строку | INCLUDE нужных столбцов в индекс |
Совет: Системное представление sys.dm_db_missing_index_details покажет, какие индексы SQL Server рекомендует создать.
Однако не создавайте их слепо: СУБД предлагает их под конкретный запрос, не анализируя общую картину. Избыток индексов серьезно замедлит операции INSERT/UPDATE/DELETE».
Но не создавайте все подряд: каждый лишний индекс замедляет INSERT, UPDATE и DELETE - особенно на нагруженных таблицах.
2. Настройка сервера с нуля:
Первоначальная установка и конфигурация закладывает фундамент производительности на годы вперёд. Исправлять плохие настройки на работающем production - значительно дороже.
MAXDOP: для серверов с ≤8 ядрами на NUMA-узел - равен числу ядер. При >8 ядрах - половина ядер на узел, но не более 8. Для гиперпоточности (HT) считайте только физические ядра
Внимание: TempDB
TempDB пересоздаётся при каждом перезапуске. Все настройки размера файлов TempDB нужно прописывать в конфигурации, а не задавать вручную после старта.
3. Конфигурация новой базы данных:
При создании новой базы закладывайте правильные параметры сразу - это экономит часы работы в будущем при росте объёма данных.
|
|
|
|||
| Начальный размер .mdf | Заложить 120–150% от ожидаемого объёма за 6 мес | Исключает Autogrowth в рабочее время | |||
| Autogrowth (.mdf) | Фиксированный прирост, не %; например 1–4 ГБ | % прирост на больших базах создаёт огромные операции | |||
| Начальный размер .ldf | 25–30% от размера .mdf |
Снижает частоту VLF-фрагментации VLF-фрагментации (Virtual Log Files - внутренние сегменты журнала; их избыток замедляет восстановление и backup журнала). |
|||
| Recovery Model | FULL для PROD, SIMPLE для DEV/QA | FULL обязателен для log shipping и резервных копий журнала | |||
| Page Verify | CHECKSUM | Обнаружение повреждений данных на диске | |||
| Auto Close | OFF | Auto Close сбрасывает кеш буферного пула | |||
| Auto Shrink | OFF | Shrink фрагментирует данные и нагружает I/O | |||
| Compatibility Level | Максимальный для версии SQL |
Новые оптимизаторные фичи доступны только при высоком уровне совместимости. Устанавливать максимальный для текущей версии SQL - но только после тестирования в staging: повышение уровня совместимости меняет поведение оптимизатора и может изменить планы выполнения существующих запросов. |
Пример создания базы с правильными параметрами:
CREATE DATABASE [ProductionDB] ON PRIMARY ( NAME = N'ProductionDB', FILENAME = N'E:\SQLData\ProductionDB.mdf', SIZE = 10240MB, -- 10 ГБ начальный размер FILEGROWTH = 1024MB -- прирост 1 ГБ (не %) ) LOG ON ( NAME = N'ProductionDB_log', FILENAME = N'F:\SQLLog\ProductionDB_log.ldf', SIZE = 2048MB, FILEGROWTH = 512MB );
ALTER DATABASE [ProductionDB] SET RECOVERY FULL; ALTER DATABASE [ProductionDB] SET PAGE_VERIFY CHECKSUM; ALTER DATABASE [ProductionDB] SET AUTO_CLOSE OFF; ALTER DATABASE [ProductionDB] SET AUTO_SHRINK OFF; ALTER DATABASE [ProductionDB] SET QUERY_STORE = ON (OPERATION_MODE = READ_WRITE, MAX_STORAGE_SIZE_MB = 1024);
4. Перенастройка действующей базы:
На production-системе изменения вносятся поэтапно, с мониторингом. Некоторые операции требуют кратковременного обслуживания (maintenance window).
Критически важно! Перед любыми изменениями на действующей базе - полная резервная копия. Изменение коллации или recovery model может потребовать пересоздания объектов или прерывания журнальных цепочек.
| Задача | Действие | Риск | Окно |
| Обновить статистику | UPDATE STATISTICS WITH FULLSCAN | Низкий | Онлайн |
|
Реорганизация индексов |
ALTER INDEX ... REORGANIZE | Низкий | Онлайн |
| Перестройка индексов | ALTER INDEX ... REBUILD (ONLINE=ON) | Средний | Онлайн (Enterprise) |
| Включить Query Store | ALTER DATABASE ... SET QUERY_STORE = ON | Низкий | Онлайн |
| Изменить Recovery Model | ALTER DATABASE ... SET RECOVERY | Средний | Обслуживание |
| Изменить Compatibility Level | ALTER DATABASE ... SET COMPATIBILITY_LEVEL | Средний | Тест в staging |
| Дефрагментация данных | DBCC INDEXDEFRAG / REORGANIZE | Низкий | Онлайн |
5. Распределение по RAID-массивам:
Дисковая подсистема - исторически главное узкое место SQL Server. Правильное использование RAID радикально меняет производительность операций чтения/записи.
Чётность. Приемлем для архивных данных и резервных копий. RAID 5 - из-за необходимости пересчёта чётности (parity write penalty) каждая запись требует 4 операций вместо 1. Категорически не подходит для журналов транзакций и TempDB.
| Тип файла | Рекомендуемый RAID | Причина |
| Данные (.mdf/.ndf) | RAID 10 | Сбалансированная R/W нагрузка, нужна отказоустойчивость |
| Журнал транзакций (.ldf) | RAID 1 или RAID 10 | Последовательная запись, критичная надёжность |
| TempDB | RAID 10 (или отдельные SSD) | Высокая случайная R/W, восстановление не нужно |
| Резервные копии | RAID 5 или RAID 6 | Преимущественно последовательная запись, нужно много места |
| ОС и бинарные файлы SQL | RAID 1 | Минимальная нагрузка, надёжность важнее скорости |
Stripe Size (размер полосы)
Для OLTP-нагрузок рекомендуется stripe size 64 КБ - совпадает с размером страниц SQL Server. Для DWH/аналитики можно увеличить до 256 КБ для лучшей последовательной производительности. Размер stripe задаётся при создании массива в контроллере (RAID-карте) или при инициализации дискового пула. После создания массива изменить без пересоздания невозможно.
6. Стратегия размещения на SSD:
Правильное разнесение компонентов базы данных (на примере MS SQL Server, PostgreSQL или MySQL) по разным SSD-накопителям позволяет минимизировать конкуренцию за ввод-вывод (I/O) и изолировать разные типы нагрузки.
Характер нагрузки на базы данных делится на три типа: случайное чтение/запись (файлы данных), строго последовательная запись (журналы транзакций) и интенсивная временная нагрузка (TempDB / tmpdir).
Подготовка накопителей:
1. Перед распределением файлов обязательно отформатируйте SSD под нужды СУБД.
2. Размер кластера (файловая система): Для дисков с базами данных, логами и TempDB всегда выбирайте размер кластера 64 КБ вместо стандартных 4 КБ. Это оптимизирует скорость чтения-записи для крупных блоков данных СУБД.
Вариант 1: У вас есть 2 SSD
Вариант 2: У вас есть 3 SSD (Оптимальный баланс)
Вариант 3: У вас есть 4 и более SSD (Максимальная производительность)
| Кол-во SSD: | Рекомендуемая схема: |
| 2 SSD | SSD1: ОС + журнал (.ldf) + TempDB. SSD2: Данные (.mdf). Изолируем случайный I/O от последовательного |
| 3 SSD | SSD1: ОС + журнал (.ldf). SSD2: Данные (.mdf). SSD3: TempDB + Backup |
| 4 SSD | SSD1: ОС. SSD2: Данные (.mdf). SSD3: Журнал (.ldf). SSD4: TempDB |
| 6+ SSD | Data: 2–4 диска в RAID 10. Журнал: 2 диска в RAID 1. TempDB: 1–2 диска. ОС/Backup: отдельно |
NVMe vs SATA SSD: NVMe даёт в 3–5× более высокий случайный IOPS по сравнению с SATA SSD. Размещайте на NVMe: данные (.mdf) и TempDB. Журнал транзакций (.ldf) - последовательная запись, SATA SSD справляется хорошо.
Архитектурные хитрости для крупных БД:
Если у вас одна огромная база данных, которая не помещается на один быстрый SSD, используйте внутренние механизмы СУБД:
Запрещено:
7. Правила настройки дисков и ОС:
| Настройка | Параметр | Значение |
| Размер кластера NTFS | Allocation unit size | 64 КБ (для томов с данными SQL) |
| Power Plan (Windows) | Схема электропитания | High Performance -ОБЯЗАТЕЛЬНО |
| Кеш записи диска | Write Cache / Write-Back | Включён с battery-backed кешем контроллера |
| Дефрагментация | Scheduled Defragmentation | Отключить для SSD-томов |
| TRIM | fsutil behavior set DisableDeleteNotify | 0 (TRIM включён для SSD) |
| Prefetch / Superfetch | SysMain service | Отключить на выделенном SQL-сервере |
| Windows Defender | Исключения | Добавить пути к .mdf, .ldf, .bak из сканирования в реальном времени |
| NUMA | Numa Node Balancing | SQL Server автоматически привязывает потоки к NUMA-узлам |
| Huge Pages (Linux) | Transparent HugePages | Отключить (madvise) для SQL Server on Linux |
8. Перенос существующих баз:
Перенос на новые диски или серверы требует тщательного планирования. Ниже основные методы с указанием сценариев применения.
| Метод | Простой | Подходит для | Сложность |
| Backup / Restore | Да (время резервной копии) | Любой перенос, в т.ч. на другой сервер | Низкая |
| Detach / Attach | Да (время детача) | Перенос в рамках одного экземпляра или совместимых версий | Низкая |
| Перемещение файлов (ALTER DATABASE) | Краткосрочный | Перемещение файлов .mdf/.ldf на другой диск | Средняя |
| Log Shipping / Mirroring | Минимальный | Перенос без остановки или с HA. Работает на Standard Edition | Средняя |
| Always On AG | Нулевой | Крупные PROD-системы, требующие RTO ≈ 0. Только Enterprise, нужен WSFC | Очень высокая |

1. Обновить пути в метаданных:
ALTER DATABASE [ProductionDB] MODIFY FILE (NAME = N'ProductionDB', FILENAME = N'E:\SQLData\ProductionDB.mdf'); ALTER DATABASE [ProductionDB] MODIFY FILE (NAME = N'ProductionDB_log', FILENAME = N'F:\SQLLog\ProductionDB_log.ldf');
2. Перевести базу в offline:
ALTER DATABASE [ProductionDB] SET OFFLINE WITH ROLLBACK IMMEDIATE;
3. Скопировать файлы вручную (xcopy / robocopy)
4. Перевести базу обратно в online:
ALTER DATABASE [ProductionDB] SET ONLINE;
5. Проверить целостность:
DBCC CHECKDB ([ProductionDB]) WITH NO_INFOMSGS;
9. Версии SQL Server: память и объёмы:
Лимиты памяти и возможности конфигурирования существенно различаются в зависимости от версии и редакции SQL Server. Выберите версию ниже для детального сравнения.
| Редакция | Макс. RAM | Макс CPU ядер | Макс. размер БД | Ключевые фичи |
| Enterprise | Неограничена (ОС) | Неограничена | 524 ПБ | Always On AG, In-Memory OLTP, Query Store, R Services |
| Standard | 128 ГБ буферный пул | 4 сокета / 24 ядра | 524 ПБ | Basic Always On (2 узла), Query Store |
| Express | 1,4 ГБ | 4 ядра | 10 ГБ | Только для малых приложений и разработки |
SQL - 2016; SQL - 2017 ; SQL - 2019; SQL - 2022
| Версия | Главное отличие от предыдущей |
| 2016 | Query Store, Always Encrypted, R Services |
| 2017 | Linux-поддержка, Python, адаптивные планы |
| 2019 | Intelligent Query Processing (IQP), ADR - восстановление за секунды вместо минут |
| 2022 | IQP v2, Contained AG, Azure Arc, Ledger Tables |
SQL Server 2016 - статус
Mainstream support завершён. Расширенная поддержка до июля 2026. Рекомендуется планировать миграцию на 2019 или 2022.
Макс. размер БД Express
Чеклист приоритетов:
✓ Выделите данные, журналы и TempDB на разные диски/RAID
✓ Форматируйте NTFS с allocation unit 64 КБ
✓ Ограничьте max server memory, настройте MAXDOP
✓ Включите Query Store и следите за регрессиями планов
✓ Предварительно выделите файлы баз нужного размера
✓ Никогда не включайте Auto Shrink в production
✓ Регулярно обслуживайте индексы (Rebuild / Reorganize)
✓ Планируйте переход на SQL Server 2019 / 2022
✓ Распределяйте данные по типу накопителя для баланса производительности и стоимости:
