SQL Server: No New Index. No Schema Changes. 10x Faster Queries – SQL Server Batch Mode on Rowstore Deep Dive!! Part 4!
Hi guys, welcome to Part 4!!
I hope you are enjoying this series. I truly believe it can be very useful for those who use SQL Server professionally as I have been doing for more than 20 years (how time flies!).
Today we will talk about Batch Mode on Rowstore and how to make your Query run 10x Faster Without Adding Any Index
Well...in Part 3 we introduced Columnstore indexes and saw how Batch Mode execution can dramatically improve analytical queries.If you missed the previous part, you can read it here:
SQL Server Filtered Index vs Indexed View – Complete Performance ComparisonBut here’s the twist.
Starting with SQL Server 2019, you don’t always need a Columnstore index to get Batch Mode performance.
SQL Server can activate Batch Mode on Rowstore.
And sometimes… as i told you at the start of this post ....your query becomes 5x or 10x faster without adding a single index. So i suggest you to continue to read...
What Is Batch Mode?
Traditionally, SQL Server processes queries in Row Mode. That means:
- One row at a time
- One operator call per row
- High CPU overhead for large datasets
Batch Mode changes the execution model.
- Processes rows in batches (typically up to 900 rows per batch)
- Uses vectorized processing
- Reduces CPU cycles per row
- Improves aggregation and join performance dramatically
Instead of calling operators millions of times, SQL Server processes chunks of rows in a single CPU-efficient operation.
Row Mode vs Batch Mode – The Real Difference
| Feature | Row Mode | Batch Mode |
|---|---|---|
| Processing Unit | 1 row | Up to ~900 rows |
| CPU Efficiency | Lower | Much Higher |
| Aggregation Speed | Moderate | Very Fast |
| Memory Usage | Standard | Optimized |
Batch Mode is not just faster. It changes how operators internally execute.
When Does SQL Server Activate Batch Mode on Rowstore?
Batch Mode on Rowstore is available starting from:
- SQL Server 2019
- Database compatibility level 150
To enable it:
ALTER DATABASE YourDatabase
SET COMPATIBILITY_LEVEL = 150;
SQL Server may automatically choose Batch Mode if:
- The query is analytical (GROUP BY, aggregates, joins)
- Large number of rows involved
- Estimated cost justifies vectorization
No Columnstore index required.
Demo – Row Mode vs Batch Mode
Let’s test a large aggregation:
SELECT CustomerID,
SUM(Amount) AS TotalAmount
FROM dbo.Sales
GROUP BY CustomerID;
Step 1 – Compatibility Level 140 (SQL Server 2017 behavior)
ALTER DATABASE YourDatabase
SET COMPATIBILITY_LEVEL = 140;
Execution Plan:
- Hash Aggregate
- Row Mode
- High CPU consumption
Step 2 – Compatibility Level 150
ALTER DATABASE YourDatabase
SET COMPATIBILITY_LEVEL = 150;
Execution Plan now shows:
- Hash Aggregate (Batch Mode)
- Vectorized execution
- Lower CPU cost
Performance Comparison
| Compatibility Level | Execution Mode | CPU (ms) | Elapsed (ms) |
|---|---|---|---|
| 140 | Row Mode | 1200 | 1500 |
| 150 | Batch Mode | 220 | 320 |
Same query. Same indexes. Same data.
Completely different execution engine behavior.
Memory Grant Feedback
SQL Server 2019 also improves memory management using Memory Grant Feedback.
If the first execution:
- Overestimates memory → wastes resources
- Underestimates memory → spills to tempdb
SQL Server adjusts the memory grant for subsequent executions.
Combined with Batch Mode, this creates:
- More stable performance
- Fewer spills
- Better concurrency
Adaptive Joins
Another intelligent feature introduced in modern versions is Adaptive Joins.
Instead of choosing Nested Loop or Hash Join at compile time, SQL Server can decide at runtime based on actual row counts.
This reduces the risk of:
- Bad cardinality estimates
- Parameter sniffing side effects
- Plan instability
Batch Mode works extremely well together with Adaptive Joins.
Why This Matters
Until SQL Server 2017, getting Batch Mode required Columnstore.
From SQL Server 2019 onward, you may gain analytical acceleration without changing your schema.
That means:
- No additional index maintenance
- No extra storage
- No schema redesign
Sometimes performance is not about adding objects.
It’s about enabling the right execution model.
Final Thoughts
Filtered Index reduces I/O.
Indexed View removes aggregation cost.
Columnstore changes the storage engine.
Batch Mode on Rowstore changes the execution engine.
And that is a completely different level of optimization.
In performance tuning, the biggest gains often come not from adding more indexes, but from understanding how SQL Server really executes your queries.
See you in Part 5 😉

Comments
Post a Comment