If you are still troubleshooting performance using only execution plans and DMVs, you are working the hard way.
Query Store is like a black box flight recorder for your database.
It captures:
โ Query history
โ Execution plans
โ Performance statistics
โ Plan changes over time
This makes performance troubleshooting dramatically easier.
1๏ธโฃ What is Query Store?
Query Store is a built-in feature introduced in Microsoft SQL Server 2016.
It automatically stores:
- Query text
- Execution plans
- Runtime statistics
- Historical performance data
๐ Even after SQL Server restart.
2๏ธโฃ Why Query Store is Powerful
Without Query Store:
- You troubleshoot only live queries.
- Historical performance is lost.
With Query Store:
- You compare past vs current performance.
- You detect plan regressions.
- You force stable plans if needed.
3๏ธโฃ Enabling Query Store
ALTER DATABASE MyDatabase
SET QUERY_STORE = ON;
Recommended settings:
ALTER DATABASE MyDatabase
SET QUERY_STORE (
OPERATION_MODE = READ_WRITE,
CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 30),
DATA_FLUSH_INTERVAL_SECONDS = 900
);
๐ Always enable it in production databases.
4๏ธโฃ Viewing Query Store Data
Using SSMS GUI:
Database โ Query Store โ Top Resource Consuming Queries
Or use query:
SELECT *
FROM sys.query_store_query;
5๏ธโฃ Detecting Plan Regression
What is Plan Regression?
When:
- Same query
- New execution plan
- Suddenly becomes slow
Query Store lets you compare:
โ Old plan
โ New plan
โ Performance differences
6๏ธโฃ Forcing a Stable Plan
If a new plan is bad:
EXEC sp_query_store_force_plan
@query_id = 10,
@plan_id = 5;
โ Forces known good plan
โ Quick production fix
โ Use carefully. Always test first.
7๏ธโฃ Finding Top CPU Consuming Queries
SELECT TOP 10
qsqt.query_sql_text,
qsr.avg_cpu_time,
qsr.avg_duration
FROM sys.query_store_query_text qsqt
JOIN sys.query_store_query qsq
ON qsqt.query_text_id = qsq.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id = qsp.query_id
JOIN sys.query_store_runtime_stats qsr
ON qsp.plan_id = qsr.plan_id
ORDER BY qsr.avg_cpu_time DESC;
๐ Perfect for performance tuning.
8๏ธโฃ Identifying Frequently Failing Queries
Query Store tracks execution stats like:
- Count
- Duration
- Resource usage
You can identify:
โ Queries running too often
โ Queries consuming too much IO
9๏ธโฃ Query Store vs DMVs
| Feature | DMVs | Query Store |
|---|---|---|
| Historical Data | โ Lost after restart | โ Saved |
| Plan History | โ No | โ Yes |
| Plan Forcing | โ No | โ Yes |
๐ Query Store is superior for long-term analysis.
๐ Real Production Scenario
โ Issue
After index rebuild, application became slow.
๐ Root Cause
New execution plan generated.
โ Fix
- Compared old vs new plan in Query Store
- Forced previous stable plan
- Performance restored immediately
1๏ธโฃ1๏ธโฃ Best Practices for Query Store
โ Enable on all production databases
โ Monitor storage size
โ Clean up old data
โ Avoid forcing too many plans
โ Review top resource-consuming queries weekly
1๏ธโฃ2๏ธโฃ When NOT to Force Plans
โ When data distribution changes
โ When index structure changes
โ When schema changes
๐ Forcing wrong plan can worsen performance.
1๏ธโฃ3๏ธโฃ Monitoring Query Store Size
SELECT current_storage_size_mb,
max_storage_size_mb
FROM sys.database_query_store_options;
1๏ธโฃ4๏ธโฃ Query Store Configuration Checklist
โ Enabled
โ READ_WRITE mode
โ Automatic cleanup
โ Regular monitoring
โ Plan forcing only when required
โ๏ธ Conclusion
Query Store turns performance tuning from guessing into data-driven decision making.
If you master Query Store, you become:
โ Faster at troubleshooting
โ More confident in production
โ A performance specialist
