SQL Server Query Tuner
Tuning Workflow
Query tuning follows this process:
- Collect - Gather the query, execution plan, and context
- Diagnose - Identify root causes (scans, spills, bad estimates, anti-patterns)
- Recommend - Suggest indexes, rewrites, or configuration changes
- Deliver - Present findings with tuned query and explanation
Step 1: Collect
Determine input type:
User pastes a query?
- Ask for the execution plan if not provided (XML preferred, graphical description accepted)
- Ask for table schemas/row counts if not obvious from plan
- Ask which SQL Server version they're on if relevant
User has a live SQL Server connection?
- Use
sqlcmd or the connection tool available to run DMV queries
- See references/dmv-queries.md for ready-to-use diagnostic queries
- Collect: actual execution plan, table/index metadata, wait stats
User pastes an XML execution plan?
- Parse it directly - look for
RelOp, IndexScan, Sort, Hash Match, estimated vs actual rows
Step 2: Diagnose
Check for these issues in priority order:
- Table/index scans on large tables (should be seeks)
- Estimated vs actual row mismatches (bad cardinality estimates)
- Key lookups with high execution count (missing covering index)
- Sort/Hash spills to tempdb (memory grant issues)
- Implicit conversions in predicates (type mismatches killing index usage)
- Parameter sniffing indicators (plan reuse with bad estimates)
- Scalar UDF calls in SELECT/WHERE (row-by-row execution)
- Cursor/RBAR patterns (row-by-agonizing-row)
See references/anti-patterns.md for the full anti-pattern catalog with examples and fixes.
See references/execution-plan-guide.md for reading execution plan operators and warnings.
Step 3: Recommend
For each issue found, provide:
- What: The specific problem identified
- Why: How it impacts performance
- Fix: The concrete change (index DDL, rewritten query, or config change)
- Impact: Expected improvement (high/medium/low)
Index Recommendations
When suggesting indexes:
- Include the full
CREATE INDEX statement with INCLUDE columns
- Check for existing indexes that overlap (consolidate, don't duplicate)
- Flag if a new index would be a superset of an existing one
- Consider write overhead - note if the table is write-heavy
- Suggest
DROP INDEX for redundant indexes being replaced
Query Rewrites
When rewriting queries:
- Show the original and rewritten side by side
- Explain what changed and why
- Preserve exact semantic equivalence (same results, same order if ORDER BY present)
- Common rewrites: correlated subquery to JOIN, scalar UDF to inline expression, CURSOR to set-based, OR to UNION ALL, functions on columns to SARGable form
Step 4: Deliver
Present findings using this structure:
## Query Tuning Report
### Summary
[One-line: what was wrong and what to do about it]
### Issues Found
1. [Issue] - [Impact: High/Medium/Low]
- Problem: [what's happening]
- Fix: [what to change]
### Recommended Indexes
[CREATE INDEX statements, if any]
### Optimized Query
[Rewritten SQL, if applicable]
### Additional Notes
[Parameter sniffing concerns, statistics update suggestions, etc.]
Live Server Diagnostics
When connected to a live SQL Server, use DMV queries from references/dmv-queries.md to:
- Pull top expensive queries by CPU/reads/duration
- Check missing index DMVs
- Review wait statistics
- Examine index usage stats (seeks vs scans vs unused)
- Check for blocking and deadlocks
Always use SET NOCOUNT ON and SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED for diagnostic queries to minimize impact.
Key Principles
- Never recommend
NOLOCK hints as a tuning fix (masks problems, risks dirty reads)
- Prefer SARGable predicates - no functions wrapping indexed columns
- Favor covering indexes over wide table scans
- Consider the full workload, not just one query in isolation
- UPDATE STATISTICS or REBUILD INDEX are maintenance, not query tuning - suggest them only when stale stats are the proven root cause
1---2name: sql-server-query-tuner3description: SQL Server query performance tuning and optimization. Analyzes execution plans, identifies anti-patterns, recommends indexes, rewrites slow queries, and diagnoses performance bottlenecks. Use when the user wants to: (1) tune or optimize a slow SQL Server query, (2) analyze an execution plan (XML or pasted), (3) find missing indexes or redundant indexes, (4) rewrite a query for better performance, (5) run DMV diagnostic queries against a live SQL Server instance, (6) understand why a query is slow, (7) review query statistics or wait stats, or any SQL Server performance-related request. Triggers on: "tune this query", "why is this slow", "optimize this SQL", "check execution plan", "missing indexes", "query performance", "SQL Server slow", "index recommendations", "rewrite this query".4---56# SQL Server Query Tuner78## Tuning Workflow910Query tuning follows this process:11121. **Collect** - Gather the query, execution plan, and context132. **Diagnose** - Identify root causes (scans, spills, bad estimates, anti-patterns)143. **Recommend** - Suggest indexes, rewrites, or configuration changes154. **Deliver** - Present findings with tuned query and explanation1617## Step 1: Collect1819Determine input type:2021**User pastes a query?**22- Ask for the execution plan if not provided (XML preferred, graphical description accepted)23- Ask for table schemas/row counts if not obvious from plan24- Ask which SQL Server version they're on if relevant2526**User has a live SQL Server connection?**27- Use `sqlcmd` or the connection tool available to run DMV queries28- See [references/dmv-queries.md](references/dmv-queries.md) for ready-to-use diagnostic queries29- Collect: actual execution plan, table/index metadata, wait stats3031**User pastes an XML execution plan?**32- Parse it directly - look for `RelOp`, `IndexScan`, `Sort`, `Hash Match`, estimated vs actual rows3334## Step 2: Diagnose3536Check for these issues in priority order:37381. **Table/index scans** on large tables (should be seeks)392. **Estimated vs actual row** mismatches (bad cardinality estimates)403. **Key lookups** with high execution count (missing covering index)414. **Sort/Hash spills** to tempdb (memory grant issues)425. **Implicit conversions** in predicates (type mismatches killing index usage)436. **Parameter sniffing** indicators (plan reuse with bad estimates)447. **Scalar UDF calls** in SELECT/WHERE (row-by-row execution)458. **Cursor/RBAR patterns** (row-by-agonizing-row)4647See [references/anti-patterns.md](references/anti-patterns.md) for the full anti-pattern catalog with examples and fixes.4849See [references/execution-plan-guide.md](references/execution-plan-guide.md) for reading execution plan operators and warnings.5051## Step 3: Recommend5253For each issue found, provide:5455- **What**: The specific problem identified56- **Why**: How it impacts performance57- **Fix**: The concrete change (index DDL, rewritten query, or config change)58- **Impact**: Expected improvement (high/medium/low)5960### Index Recommendations6162When suggesting indexes:63- Include the full `CREATE INDEX` statement with `INCLUDE` columns64- Check for existing indexes that overlap (consolidate, don't duplicate)65- Flag if a new index would be a superset of an existing one66- Consider write overhead - note if the table is write-heavy67- Suggest `DROP INDEX` for redundant indexes being replaced6869### Query Rewrites7071When rewriting queries:72- Show the original and rewritten side by side73- Explain what changed and why74- Preserve exact semantic equivalence (same results, same order if ORDER BY present)75- Common rewrites: correlated subquery to JOIN, scalar UDF to inline expression, CURSOR to set-based, OR to UNION ALL, functions on columns to SARGable form7677## Step 4: Deliver7879Present findings using this structure:8081```82## Query Tuning Report8384### Summary85[One-line: what was wrong and what to do about it]8687### Issues Found881. [Issue] - [Impact: High/Medium/Low]89 - Problem: [what's happening]90 - Fix: [what to change]9192### Recommended Indexes93[CREATE INDEX statements, if any]9495### Optimized Query96[Rewritten SQL, if applicable]9798### Additional Notes99[Parameter sniffing concerns, statistics update suggestions, etc.]100```101102## Live Server Diagnostics103104When connected to a live SQL Server, use DMV queries from [references/dmv-queries.md](references/dmv-queries.md) to:105106- Pull top expensive queries by CPU/reads/duration107- Check missing index DMVs108- Review wait statistics109- Examine index usage stats (seeks vs scans vs unused)110- Check for blocking and deadlocks111112Always use `SET NOCOUNT ON` and `SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED` for diagnostic queries to minimize impact.113114## Key Principles115116- Never recommend `NOLOCK` hints as a tuning fix (masks problems, risks dirty reads)117- Prefer SARGable predicates - no functions wrapping indexed columns118- Favor covering indexes over wide table scans119- Consider the full workload, not just one query in isolation120- UPDATE STATISTICS or REBUILD INDEX are maintenance, not query tuning - suggest them only when stale stats are the proven root cause