SQL Server performance tuning is a cycle: measure how the server behaves today, find the queries and resources that hold it back, change one thing, and measure again. The tools are built in. Query Store, dynamic management views (DMVs) and actual execution plans cover most of what a small or mid-size business needs. This guide walks through the cycle in order, with the indexing and monitoring decisions that matter most, and explains when it makes sense to hand the work to a managed IT team.
TL;DR
- Capture a performance baseline first. Without it you cannot tell whether a change helped.
- Use Query Store and the DMVs to find the slowest and most expensive queries, then compare elapsed time with CPU time to learn why they are slow.
- Fix causes in this order: stale statistics, missing or poorly designed indexes, then query rewrites. Over-indexing slows writes.
- Track waits, CPU, disk I/O and memory over time, and keep transactions short to limit blocking.
- Verify every change against the baseline, and keep the previous plan available so you can roll back.
Table of Contents
- Start with a baseline, not a guess
- Find the slow queries
- Read the execution plan
- Statistics and parameter sniffing
- Build an indexing strategy that helps and does not hurt
- Monitor the metrics that reveal trouble
- Resolve blocking and deadlocks
- Prove that the change helped
- Our perspective: tune before you buy hardware
- When to bring in a managed IT partner
- FAQ
- Sources
Start with a baseline, not a guess
The most common tuning mistake is changing settings or adding indexes before anyone knows what normal looks like. Microsoft's guidance on monitoring and tuning for performance describes two complementary habits: take periodic snapshots to isolate a specific problem, and gather data continuously so you can see trends. It also frames tuning as watching query response times to decide whether query or index changes are needed, and as establishing a baseline to compare against.
A useful baseline for a business database is small and boring:
- Query response times for the five to ten operations users complain about most, such as loading a client record, running a daily report or posting a payment.
- Server resources during business hours and during batch jobs: CPU, memory, disk I/O and network traffic. Microsoft names efficient network traffic, disk I/O and CPU usage as the keys to peak SQL Server performance.
- Query Store data, which keeps a history of queries, plans and runtime statistics so you can review them after the fact.
- Wait statistics, covered below, which show what queries spent their time waiting for.
Write down the date, the workload at the time (month-end close and a quiet Tuesday look nothing alike) and any recent changes such as patches, new application releases or data growth. A baseline taken on a quiet day can make a normal busy day look like an incident.
Find the slow queries
Most performance complaints trace back to a small number of statements. Microsoft's guide to troubleshooting slow-running queries names three places to look:
- Query Store, for history over time and for regressions after a change.
- sys.dm_exec_requests, for statements that are running right now.
- sys.dm_exec_query_stats, for aggregated statistics on statements that already ran.
Once you have a suspect, compare its elapsed time with its CPU time. The comparison tells you which kind of problem you have. If CPU time is close to elapsed time, the query is busy doing work, and the fix is usually a better plan, a better index or a rewrite. If elapsed time is much larger than CPU time, the query spent most of its life waiting, and you should look at what it waited for: locks, disk, memory grants or something else.
Microsoft's documentation on detectable types of query performance bottlenecks uses the same split. Problems are generally running-related or waiting-related. Although that page is written for Azure SQL, the query-level reasoning carries over to SQL Server you host yourself.
Use Query Store as your flight recorder
Query Store, available in SQL Server 2016 and later, identifies queries with suboptimal performance and keeps a history of their execution plans. That history matters for the most frustrating scenario in small-business IT: a report that ran in seconds last week and takes minutes today. With Query Store you can see whether the plan changed, and if an older plan was better, a DBA can force it while the root cause is investigated.
The same documentation notes that Query Store can show wait statistics per query over time, grouped into categories. The sys.query_store_wait_stats view maps those categories to the underlying wait types, so you can move from "this query is slow" to "this query is mostly waiting on locks" without guessing.
Avoid heavy tracing on a production server just to catch slow statements. Tracing tools can slow the very queries you are trying to measure, and Query Store plus plan cache analysis give you the same answers with less overhead.
Read the execution plan
An actual execution plan shows how SQL Server really ran a query: which indexes it used, how many rows each step produced and where the work went. Read it from the right, where data is first read, toward the left, where results are returned.
What to check first:
- Estimated rows versus actual rows. A large gap means the optimizer made its choices on bad information, which usually points to statistics.
- Scans on large tables where you expected a seek. This often means a missing or unusable index.
- Lookups repeated many times, which suggest an index that almost covers the query but not quite.
- Warnings for spills to disk or implicit conversions, which can both hide in otherwise reasonable plans.
If a query was faster in the past or is faster on another database, compare the two actual execution plans to see whether they differ. Different plans for the same query are a strong clue, and they lead directly to the next topic.
Statistics and parameter sniffing
SQL Server uses statistics to estimate how many rows each step will return, and those estimates drive plan decisions. When statistics are out of date after large data loads, deletes or fast growth, the optimizer can pick a poor plan. Updating statistics is cheap, and it is one of the first things to try according to Microsoft's slow-query troubleshooting steps, alongside applying missing indexes or rewriting the query.
Parameter sniffing is the related pattern where a stored procedure is compiled for one parameter value and then reused for very different values. A lookup for a client with ten records and one for a client with a million records should not necessarily share a plan. Common quick fixes, such as evicting the specific plan from the cache or updating statistics, are temporary relief. The durable fix starts with examining the plans produced for different parameter values, then choosing a rewrite or plan strategy that suits both.

Build an indexing strategy that helps and does not hurt
Indexes are the most powerful tuning lever and the easiest to overuse. Each one speeds some reads and adds cost to every insert, update and delete that touches the table.
Microsoft's index design guide gives the balance: for transactional (OLTP) workloads, a few narrow rowstore indexes aimed at the critical queries are a good starting point, while for analytical (OLAP) workloads clustered columnstore indexes are especially appropriate. It also warns that over-indexing heavily updated tables hurts data modification performance and adds storage and update costs.
| Workload | Typical starting point | Main risk |
|---|---|---|
| OLTP (orders, payments, patient or client records) | A few narrow nonclustered rowstore indexes on the columns your critical queries filter and join on | Too many indexes slow writes and use storage |
| Reporting and analytics | Clustered columnstore indexes | Poor fit for frequent single-row updates |
| Mixed | Keep reporting off the primary where possible | Heavy reports block or slow transactions |
A practical sequence:
- Start from the queries you identified in Query Store, not from a list of every missing-index suggestion.
- Design each index for several queries when you can, rather than one index per query.
- Check for existing indexes that overlap or are never used before adding another.
- Test on a copy with realistic data volumes, because an index that looks great on 10,000 rows may behave differently on 50 million.
The Database Engine Tuning Advisor can analyze a database and a workload and recommend indexes, indexed views and partitions. Treat its output as a list of candidates to review, not a script to run. Someone who understands the application should confirm that each recommendation justifies its write cost.
Storage layout affects index performance too, since fast reads depend on the disks beneath the database. If you are planning storage for a new server, our RAID calculator shows usable capacity and fault tolerance for common RAID levels.
Monitor the metrics that reveal trouble
Good monitoring answers three questions: is the server healthy right now, is it changing over time, and which query is responsible? These are the categories we watch.
| Metric group | What it tells you | How to read it |
|---|---|---|
| Wait statistics | What queries spend time waiting for: locks, I/O, tempdb contention, memory grants | Look at the top waits over a period, not a single snapshot |
| CPU | Whether queries are compute-bound | Sustained high CPU with high query CPU time points to plans and indexes |
| Disk I/O | Read and write latency on data and log files | Rising latency during normal load suggests storage limits or missing indexes causing scans |
| Memory | Whether data and plans stay cached | Frequent memory grant waits point to large sorts or hashes, often from poor plans |
| Network traffic | Volume between application and server | Unusually large result sets often mean the application fetches more than it needs |
| Blocking | Sessions waiting on other sessions | Any sustained blocking chain deserves investigation |
The waiting-related category in Microsoft's bottleneck guidance includes locks, I/O, tempdb contention and memory grant waits, which is why wait statistics sit at the top of the list. Pair them with your baseline: a number only means something compared with what the same server did last month.
Monitoring only works if someone is looking. Alerts that go to an unattended mailbox at 2 a.m. do not protect anyone. Our article on 24/7 network monitoring covers how to put round-the-clock watching in place without hiring a night shift.
Resolve blocking and deadlocks
Blocking happens when one session holds locks that another needs. A little is normal. A long chain means users are staring at spinning screens.
Microsoft's guidance on blocking problems gives clear direction on prevention: keep transactions short and reduce the lock footprint of expensive queries, which also helps prevent lock escalation. The same page offers a useful design option: if a long-running query blocks users and cannot be optimized, consider moving it out of the transactional environment to a dedicated reporting system or a read-only replica. For options that keep a readable secondary available, see our guide to SQL Server high availability.
Deadlocks are different: two sessions each hold something the other needs, and SQL Server ends one of them. Microsoft engineers' deadlock troubleshooting notes describe two durable fixes: make code acquire resources in a consistent order, or use a covering index that removes the need for one of the competing access paths. Retrying the failed transaction in the application is a sensible safety net, but it does not replace fixing the cause.

Prove that the change helped
Every tuning change needs a before and after. A reliable routine:
- Record the baseline metrics and the Query Store runtime statistics for the target queries.
- Change one thing at a time, ideally in a test environment with production-sized data.
- Run the same workload and compare duration, CPU, reads and waits against the baseline.
- After release to production, review Query Store for plan regressions in neighboring queries, since an index or statistics change can alter plans elsewhere.
- Keep notes on what changed and why, so the next person does not undo it.
Query Store makes step four practical because it retains the history of plans and runtime statistics for review, as the Microsoft monitoring guidance describes. If a regression appears, you have the earlier plan on record.
Tuning also assumes you can recover if a change goes wrong. Before schema or index work on a critical database, confirm that a tested backup exists and that you know your recovery targets. Our explainer on RPO vs RTO shows how to set them.
Our perspective: tune before you buy hardware
We see the same pattern at small and mid-size businesses. A line-of-business application slows down, the first instinct is a bigger server, and the slowdown returns six months later because the underlying cause was a handful of queries and a missing maintenance routine. Hardware spending is sometimes the right answer, but it should follow measurement, not replace it.
Our approach is preventative. We prefer to find a growing wait type, a drifting backup window or a table that has outgrown its indexes before users notice. That is why we pair performance work with continuous monitoring and a regular review of the baseline, rather than waiting for a ticket that says the system is slow.
Two other points come from the regulated industries we serve. First, performance and security interact: an index on a sensitive column, a reporting copy of production data or a new tuning account all change who can see what. For databases that hold patient, client or financial records, we review these changes against HIPAA and other compliance requirements, and we suggest data masking for test and reporting copies. Second, a tuned database is only useful if it stays available. Tuning, high availability and backup planning belong in one conversation.
— Alex
When to bring in a managed IT partner
If your team has no dedicated DBA, tuning tends to happen in emergencies, one slow week at a time. Secure Techies provides managed IT services for small and mid-size businesses in Southern California, including 24/7 monitoring, infrastructure design and management, and backup and disaster recovery. For SQL Server environments, that means someone is watching the metrics above continuously, keeping a baseline, and acting on trends before they become outages. You can also look at our managed infrastructure services if the server, storage or virtualization layer is the part that needs attention, or contact us through the site to talk through a specific database.
FAQ
How do you do performance tuning in SQL Server?
Start by measuring: establish a baseline of query response times and resource use. Then find the slowest queries with Query Store and the DMVs, inspect their execution plans, and address statistics, indexes or query design as the evidence suggests. Finish by comparing results with the baseline.
How do you fix slow-running queries in SQL Server?
Compare the query's elapsed time with its CPU time to see whether it is busy or waiting. Then examine the plan and consider updating statistics, adding a missing index or rewriting the query. If the query used to be fast, compare the old and new plans, because a plan change is a common cause.
Can too many indexes slow SQL Server down?
Yes. Every index must be maintained on each insert, update and delete, so over-indexing a heavily updated table hurts data modification performance and adds storage cost. Begin with a few narrow indexes aimed at your critical queries and add more only when measurements justify them.
Which SQL Server metrics matter most?
Wait statistics, CPU, disk I/O, memory and network traffic give the broadest picture. Waits show whether queries are held up by locks, I/O, tempdb contention or memory grants, and trends against a baseline matter more than any single reading.
Sources
- Monitor and Tune for Performance, Microsoft Learn
- Troubleshoot Slow-Running Queries in SQL Server, Microsoft Learn
- Tune performance with the Query Store, Microsoft Learn
- Detectable types of query performance bottlenecks, Microsoft Learn
- How to Start Troubleshooting Parameter Sniffing Issues
- Index Architecture and Design Guide, Microsoft Learn
- Database Engine Tuning Advisor, Microsoft Learn
- Understand and Resolve SQL Server Blocking Problems, Microsoft Learn
- Deadlock Troubleshooting, Part 3, Microsoft Learn archive
