Web Analytics Made Easy - Statcounter
Home » SQL Server » Performance Tuning » SQL Server Memory Grant Problems: How to Find Queries That Use Too Much Memory

SQL Server Memory Grant Problems: How to Find Queries That Use Too Much Memory

Sql Server Memory Grant Problems How To Find Queries That Use Too Much Memory
SQL Server Memory Grant Problems: How to Find Queries That Use Too Much Memory

Introduction

When a query is slow, spills to tempdb, or other queries suddenly start waiting for memory, don’t look only at CPU and logical reads.

Check the query’s memory grant.

SQL Server gives certain queries workspace memory for operations such as sorts and hash joins. A grant that is too small can cause expensive spills to disk; a grant that is too large can waste memory and reduce concurrency.

A useful troubleshooting sequence is:

Slow Query
    ↓
Check Execution Plan
    ↓
Check Memory Grant
    ↓
Look for Sort/Hash Spills
    ↓
Investigate Statistics / Cardinality / Query Design
    ↓
Retest

Explanation

Consider this query:

SELECT
    CustomerID,
    SUM(OrderAmount) AS TotalSales
FROM dbo.Orders
GROUP BY CustomerID
ORDER BY TotalSales DESC;

The database may need memory for:

  • Hash aggregation
  • Sorting
  • Other execution operators

If the optimizer underestimates how much memory is required, the query may receive too small a grant and spill intermediate data to tempdb.

If it overestimates, the query may reserve much more memory than it actually needs.

Microsoft describes both situations as important performance problems: excessive grants can reduce concurrency, while insufficient grants can cause expensive disk spills.

Real-World Example

Imagine a reporting workload with 50 concurrent queries.

One query requests a very large memory grant:

Query A → 8 GB
Query B → 500 MB
Query C → 300 MB
Query D → 400 MB
...

Even if Query A doesn’t actually use all 8 GB, that large reservation can reduce the memory available for other concurrent queries.

The result can look like:

Application
    ↓
Queries become slow
    ↓
CPU looks normal
    ↓
Users report timeouts
    ↓
Memory grant waits discovered

This is why high CPU isn’t the only resource problem worth investigating.

Find Current Memory Grants

You can inspect queries that have requested or received execution memory with:

SELECT
    session_id,
    request_time,
    grant_time,
    requested_memory_kb,
    granted_memory_kb,
    required_memory_kb,
    used_memory_kb,
    max_used_memory_kb,
    wait_time_ms,
    is_next_candidate
FROM sys.dm_exec_query_memory_grants
ORDER BY granted_memory_kb DESC;

sys.dm_exec_query_memory_grants returns queries that are waiting for or have received a memory grant. Sort and hash operations are examples of operations that can require these grants.

On SQL Server, the required permissions depend on version; Azure SQL Database uses database-level permissions such as VIEW DATABASE STATE.

A More Useful Diagnostic Query

To identify the SQL text associated with current memory grants:

SELECT
    mg.session_id,
    mg.requested_memory_kb,
    mg.granted_memory_kb,
    mg.used_memory_kb,
    mg.max_used_memory_kb,
    mg.wait_time_ms,
    st.text AS sql_text
FROM sys.dm_exec_query_memory_grants AS mg
OUTER APPLY sys.dm_exec_sql_text(mg.sql_handle) AS st
ORDER BY mg.granted_memory_kb DESC;

Look for queries where:

Granted Memory >> Used Memory

or queries that are waiting for a grant.

But remember: a large grant is not automatically a problem. A large analytical query may legitimately need substantial workspace memory.

What Should You Look For in the Execution Plan?

When investigating memory grants, pay particular attention to:

Sort operators

Large sorts can require significant workspace memory.

Hash Match operators

Hash joins and hash aggregates can also require memory grants.

Spill warnings

If a sort or hash operation spills to tempdb, investigate why.

Conceptually:

Memory Grant Too Small
        ↓
Sort / Hash
        ↓
Not enough workspace memory
        ↓
Spill to tempdb
        ↓
Additional I/O
        ↓
Query slows down

Why Statistics Matter

One of the most important clues is cardinality estimation.

Suppose SQL Server estimates:

10,000 rows

but the query actually processes:

10,000,000 rows

The optimizer may make poor decisions about join strategy, memory requirements, and other operators.

Microsoft specifically recommends keeping statistics current because inaccurate statistics can contribute to unnecessarily high memory grants or spills caused by underestimated memory requirements.

So when you see a memory-grant problem, don’t immediately try to manipulate the grant.

Ask:

Why did the optimizer think this query needed this much or this little memory?

Memory Grant Feedback Can Help

Modern SQL Server versions and Azure SQL can use Memory Grant Feedback to adjust memory grants based on previous executions.

The goal is to:

Too Little Memory
      ↓
Spill
      ↓
Feedback
      ↓
Adjust Grant

or:

Too Much Memory
      ↓
Wasted Memory
      ↓
Feedback
      ↓
Reduce Grant

Row-mode memory grant feedback is available from SQL Server 2019 and Azure SQL at the appropriate compatibility level. SQL Server 2022 introduced persistent/percentile improvements, and Azure SQL Database supports these newer capabilities.

However, don’t use Memory Grant Feedback as a reason to ignore a fundamentally inefficient query.

If a query is processing far more rows than necessary, fix the query and data-access pattern first.

Best Practices

1. Look at the actual execution plan

Check:

  • Memory Grant Info
  • Granted Memory
  • Used Memory
  • Sort warnings
  • Hash warnings
  • Estimated vs actual rows

2. Keep statistics current

Bad cardinality estimates can contribute to memory-grant problems.

3. Reduce unnecessary rows early

Filtering data earlier can reduce the amount of data that downstream sort/hash operations must process.

4. Review indexes

An appropriate index can sometimes reduce scans, sorting, or other expensive operations.

5. Check concurrency

One large grant may be manageable.

Twenty simultaneous large grants may not be.

6. Understand Memory Grant Feedback

It can automatically adjust repeated workloads, but it isn’t a substitute for query tuning.

7. Measure before and after

Don’t change a query or index simply because the memory grant looks large.

Measure:

Duration
CPU
Logical Reads
Spills
Granted Memory
Used Memory
Concurrency

Common Mistakes to Avoid

Mistake 1: Assuming every large memory grant is bad

A large query may legitimately require a large grant.

Mistake 2: Looking only at granted_memory_kb

Compare the grant with actual usage and workload behavior.

Mistake 3: Ignoring spills

A query that repeatedly spills to tempdb deserves investigation.

Mistake 4: Immediately increasing server memory

More memory may help capacity, but it doesn’t fix bad cardinality estimates or inefficient query design.

Mistake 5: Using MAX_GRANT_PERCENT as the first solution

Query hints can be useful in specific situations, but they should not replace understanding why the optimizer requested the memory in the first place.

Mistake 6: Ignoring statistics

Statistics are often part of the root cause.

Pro Tip

When troubleshooting a slow query, add memory grant analysis to your standard checklist:

CPU
Logical Reads
Physical Reads
Waits
Blocking
Execution Plan
Cardinality Estimates
Memory Grant
Sort/Hash Spills
Statistics

This is especially valuable for reporting, ETL, aggregation, and analytical workloads, where large sorts and hash operations are common.

Summary

A query can be slow not because it lacks CPU, but because it received the wrong amount of execution memory. So, check memory grants and spills when troubleshooting serious SQL Server performance problems.


Discover more from Technology with Vivek Johari

Subscribe to get the latest posts sent to your email.

Leave a Reply

Scroll to Top

Discover more from Technology with Vivek Johari

Subscribe now to keep reading and get access to the full archive.

Continue reading