Распределение памяти (memory grants) под запросы — один из ключевых и при этом часто недооцениваемых аспектов настройки производительности SQL Server. Если запрос просит больше памяти, чем ему нужно, падает параллелизм. Если слишком мало — происходят проливы в tempdb.
В SQL Server 2025 Microsoft улучшила обратную связь по распределению памяти запроса (query memory grant feedback) и оптимизацию планов выполнения, благодаря чему движок управляет памятью заметно эффективнее, чем в SQL Server 2022. В этой статье мы рассмотрим, как эти изменения влияют на производительность запросов, сравним уровни совместимости 160 и 170.
Почему важно, сколько памяти потребляет запрос
Каждый запрос в SQL Server запрашивает распределение памяти — зарезервированный объём для операций сортировки и хеширования. Когда один запрос потребляет слишком много, остальные ждут на семафоре ресурсов, что блокирует параллелизм.
Механизм обратной связи по распределению памяти (memory grant feedback, появился в 2017) корректирует распределение, опираясь на предыдущие исполнения. В SQL Server 2025 этот цикл обратной связи стал быстрее и точнее.
Итог: более стабильное потребление памяти и меньше впустую потраченной ОЗУ на каждый запрос.
Подготовка тестового окружения
Для демонстрации используем:
- SQL Server 2025 RC0 или RC1
- Тестовую базу StackOverflow (свободно доступна на StackOverflow.com)
- Запрос, находящий топ‑100 пользователей с наивысшей репутацией, возвращающий только лучшего пользователя по каждой локации.
Шаг 1 — тест на уровне совместимости 160 (SQL Server 2022)
Сначала переключите базу на уровень совместимости 160 и выполните следующий запрос.
USE master;
GO
ALTER DATABASE StackOverflow SET COMPATIBILITY_LEVEL = 160;
GO
USE StackOverflow;
GO
;WITH Tbl AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY u.Location ORDER BY u.Reputation DESC) AS rn,
u.Id, u.Age, u.CreationDate, u.DisplayName, u.DownVotes,
u.EmailHash, u.LastAccessDate, u.Location, u.Reputation,
u.UpVotes, u.Views, u.WebsiteUrl, u.AccountId
FROM dbo.Users u
WHERE u.Location IS NOT NULL AND Location <> ''
)
SELECT TOP 100
t.Id, t.Age, t.CreationDate, t.DisplayName, t.Reputation, t.Location
FROM Tbl t
WHERE t.rn = 1
ORDER BY t.Reputation DESC;
GO
Чтобы зафиксировать детали по памяти, включите Include Actual Execution Plan в SSMS (Ctrl + M).
Вы увидите, что оптимизатор выполняет сканирование кластерного индекса и использует операторы Sort и Window Aggregate. Это необходимо, чтобы вычислить функцию ROW_NUMBER() и упорядочить результат по репутации.
Наблюдение за распределением памяти
Щёлкните правой кнопкой по оператору SELECT в плане выполнения и откройте Properties.
Вы заметите:
- Granted Memory: ~2700 MB
- IsMemoryGrantFeedbackAdjusted:
No (First Execution)
Выполните тот же запрос ещё три раза:
GO 3
Теперь распределение памяти сокращается примерно до 946 MB, а IsMemoryGrantFeedbackAdjusted меняется на Yes: Stable.
Это подтверждает, что обратная связь по распределению памяти успешно подстроила распределение памяти для запроса после нескольких исполнений.
Шаг 2 — тест на уровне совместимости 170 (SQL Server 2025)
Включим возможности SQL Server 2025.
ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL = 170;
GO
Выполните тот же запрос снова:
;WITH Tbl AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY u.Location ORDER BY u.Reputation DESC) AS rn,
u.Id, u.Age, u.CreationDate, u.DisplayName, u.Reputation, u.Location
FROM dbo.Users u
WHERE u.Location IS NOT NULL AND Location <> ”
)
SELECT TOP 100
t.Id, t.DisplayName, t.Reputation, t.Location
FROM Tbl t
WHERE t.rn = 1
ORDER BY t.Reputation DESC;
GO
Сравнение планов выполнения
План запроса теперь немного меняется. Оптимизатор фильтрует результаты до финальной сортировки, снижая число промежуточных строк и потребность в памяти.
Распределение памяти: ~1427 MB
IsMemoryGrantFeedbackAdjusted: No (First Execution)
Запустите запрос ещё три раза:
GO 3
Распределение памяти стабилизируется примерно на уровне 467 MB, то есть вдвое меньше, чем при уровне совместимости SQL Server 2022.
Мониторинг семафоров ресурсов
SELECT *
FROM sys.dm_exec_query_memory_grants
WHERE grant_time IS NOT NULL
ORDER BY requested_memory_kb DESC;
Эта DMV помогает определить, какие запросы потребляют больше всего памяти и стоят ли они в очереди на распределение памяти.
Анализ в Query Store
Если Query Store включён, можно сравнить показатель Memory Grant (KB) во времени посредством запроса:
SELECT
qs.query_id,
qs.avg_memory_grant_kb,
qs.last_execution_time
FROM sys.query_store_runtime_stats qs
ORDER BY qs.avg_memory_grant_kb DESC;
Итоги
В этом тесте SQL Server 2025 на уровне совместимости 170 потребил примерно на 50% меньше памяти для той же нагрузки по сравнению с уровнем 160 (2022).
Основные выводы:
- Обратная связь по распределению памяти стала быстрее и точнее.
- Оптимизатор запросов лучше сокращает число строк до выполнения сортировок.
- Улучшения в эвристиках планов выполнения сокращают избыточное распределение памяти.
Хотя не всякая нагрузка покажет такие же цифры, тренд очевиден: SQL Server 2025 обеспечивает более экономное потребление памяти на запрос, повышая параллелизм и устойчивость на загруженных системах.
Давление на память остаётся одной из самых скрытых причин деградации производительности. SQL Server 2025 продолжает курс Microsoft на самонастраивающееся поведение — от интеллектуальной обработки запросов до адаптивных контуров обратной связи.
Если вы переходите с SQL Server 2019 или 2022, включение уровня совместимости 170 — простой способ сразу получить эти преимущества.
Всегда контролируйте DMV, Query Store и планы выполнения, чтобы подтвердить выигрыш в вашей среде, и обязательно сравнивайте показатели до и после обновления.

Комментариев нет:
Отправить комментарий