Preskočiť na obsah
Návod

Memory grant – koľko pamäte dostal dotaz (priveľa alebo primálo)

Memory Grant Info v pláne: Requested, Granted, MaxUsed a GrantWaitTime, varovanie Excessive Grant, vplyv šírky stĺpcov, memory grant feedback a čo robiť pri nadmernom alebo malom grante.

4 min čítania 4 kroky 1 obrázok SQL Server 2016+
> [!TIP]
> Recept z [kuchárky exekučných plánov](script.php?id=64&s=exekucne-plany-kucharka-zacni-tu). Ukážky bežia v testovacej databáze [PlanLab](script.php?id=65&s=planlab-testovacia-databaza-pre-recepty-exekucnych-planov) – nikdy ich nespúšťaj na produkcii.

## Ako to vyzerá v pláne

![Memory Grant Info: pridelená a použitá pamäť](uploads/2026/11/plan-p8.svg "Granted ≫ MaxUsed: pamäť zbytočne rezervovaná, iné dotazy čakajú")

Na koreňovom SELECT: **Memory Grant Info** (*SerialRequiredMemory*, *RequestedMemory*, *GrantedMemory*, *MaxUsedMemory*, *GrantWaitTime*) a v skutočnom pláne varovanie **Excessive Grant** alebo **Grant Increase** / ďalšie memory varovania. Pri SQL Server 2019+ aj *IsMemoryGrantFeedbackAdjusted* a *LastRequestedMemory*.

## Čo to znamená

Dotaz s operátormi, ktoré potrebujú pamäť (Sort, Hash Match, niektoré spooly, columnstore operácie), dostane **pred štartom** pridelenú pamäť – *memory grant*. Celková pamäť pre granty je obmedzená. Keď je grant:

- **príliš malý** → [spill do tempdb](script.php?id=90&s=spill-do-tempdb-sort-a-hash-warning-memory-grant-feedback),
- **príliš veľký** → pamäť leží nevyužitá a ďalšie dotazy **čakajú** na pridelenie (čakanie `RESOURCE_SEMAPHORE`, vlastnosť *GrantWaitTime*).

### Do hĺbky

- Veľkosť grantu = odhad riadkov × odhadovaná **šírka** riadku. Stĺpce s premenlivou dĺžkou sa rátajú ako polovica deklarovanej dĺžky (`varchar(4000)` ≈ 2 000 B), `(max)` typy pevným odhadom okolo 4 000 B – široké stĺpce v ORDER BY / GROUP BY nafukujú grant.
- Paralelný plán má väčší grant (časť pre každé vlákno).
- Jeden dotaz môže dostať najviac určité percento pamäte grantov (predvolene 25 % – nastavenie workload group v Resource Governore, `REQUEST_MAX_MEMORY_GRANT_PERCENT`).
- **Memory grant feedback** – po spustení porovná grant so skutočne použitou pamäťou a pre ďalšie spustenia ho upraví (batch 2017, row mode 2019, percentile a persistence 2022). Pri striedajúcich sa parametroch sa feedback môže vypnúť (*No: Feedback disabled*).
- Hinty `MIN_GRANT_PERCENT` / `MAX_GRANT_PERCENT` (2016+) – percentá z limitu dotazu.
- Čakajúce granty práve teraz ukáže `sys.dm_exec_query_memory_grants` – recept [Memory grants – kto čaká na pamäť](script.php?id=19&s=memory-grants-kto-caka-na-pamat-resource-semaphore).

## Kedy je to v poriadku / kedy problém

| V poriadku | Problém |
|---|---|
| MaxUsed blízko Granted | Granted ≫ MaxUsed (Excessive Grant) pri častom dotaze |
| GrantWaitTime 0 | GrantWaitTime v sekundách, RESOURCE_SEMAPHORE na serveri |
| malý grant pri OLTP dotaze | GB grant pre dotaz vracajúci pár riadkov |

## Ako si to vyskúšať

```sql
USE PlanLab;
-- 1) Rovnaký Sort, úzky vs. široký stĺpec (deklarovaná šírka nafúkne grant)
SELECT OrderID, AccountCode FROM dbo.Orders ORDER BY AccountCode;
SELECT OrderID, CAST(AccountCode AS varchar(4000)) AS siroky FROM dbo.Orders ORDER BY siroky;

-- 2) Nadhodnotený odhad → nadmerný grant (konštanta, ktorej rozsah optimalizátor nevie odhadnúť presne)
SELECT o.OrderID, o.Note FROM dbo.Orders AS o
JOIN dbo.OrderLines AS l ON l.OrderID = o.OrderID
WHERE l.Qty > 0 AND o.CustomerID IN (SELECT CustomerID FROM dbo.Customers WHERE Country = 'SK')
ORDER BY o.Note;

-- 3) Kto má grant teraz (spusti v inom okne počas behu)
SELECT session_id, requested_memory_kb, granted_memory_kb, used_memory_kb, wait_time_ms
FROM sys.dm_exec_query_memory_grants;
```

Spusti s **Include Actual Execution Plan** (Ctrl+M) a na SELECT porovnaj *Memory Grant Info* – *GrantedMemory* a *MaxUsedMemory* v oboch dotazoch bodu 1.

## Čo s tým

1. Oprav odhad (štatistiky, typy, prepis) – grant sleduje odhad.
2. Neťahaj široké stĺpce cez Sort a Hash: najprv vyber kľúče, dlhé stĺpce dočítaj až pre výsledné riadky.
3. Na 2019+ / 2022+ nechaj pracovať memory grant feedback (compat level, Query Store).
4. Ak server trpí `RESOURCE_SEMAPHORE`, nájdi dotazy s najväčšími grantmi ([čakanie RESOURCE_SEMAPHORE](waits.php#RESOURCE_SEMAPHORE)) a až potom zvažuj `MAX_GRANT_PERCENT` alebo Resource Governor.

## Súvisiace

- [Spill do tempdb](script.php?id=90&s=spill-do-tempdb-sort-a-hash-warning-memory-grant-feedback)
- [Hash Match](script.php?id=73&s=hash-match-hash-join-a-hash-aggregate-build-a-probe)
- [Sort, Top a Top N Sort](script.php?id=75&s=sort-top-a-top-n-sort-zoradovanie-a-pamat)
- [Memory grants – kto čaká na pamäť](script.php?id=19&s=memory-grants-kto-caka-na-pamat-resource-semaphore)
- [Pamäť SQL Servera a OS – rýchly prehľad](script.php?id=24&s=pamat-sql-servera-a-os-rychly-prehlad)
- [Čakanie RESOURCE_SEMAPHORE](waits.php#RESOURCE_SEMAPHORE)

## Zdroje

- [Microsoft Learn – Memory grant feedback](https://learn.microsoft.com/sql/relational-databases/performance/intelligent-query-processing-memory-grant-feedback)
- [Microsoft Learn – Query hints (Transact-SQL)](https://learn.microsoft.com/sql/t-sql/queries/hints-transact-sql-query)
- [Erik Darling – blog (plány, memory grants, parameter sniffing)](https://erikdarling.com/)
- [Brent Ozar – blog a nástroje First Responder Kit](https://www.brentozar.com/)

_Texty sú vlastné, tvrdenia overené proti uvedeným zdrojom (11/2026). T-SQL je staticky skontrolovaný, nie spustený na živom serveri – vyskúšaj ho najprv v PlanLab._