SQL Server Performance Tuning

How We Cut SQL Server Costs in Half and Added HA for Free

Updated
9 min read
Written by
Mark Varnas
Reviewed by
Saulius Baskevicius

SQL Server on an Azure VM — 8 cores, sluggish performance. The client wanted more cores. We tuned their indexing, fixed implicit conversions, and set up maintenance instead.

CPU usage dropped 20–30%.

We downsized the primary to 4 cores and used the freed budget to add a 4-core HA replica without increasing SQL licensing spend. Total monthly cost stayed roughly flat.

Key Takeaways

  • Tune before you scale — fixing indexing and implicit conversions dropped CPU 20–30% on the same hardware.
  • Table scans on large tables were the biggest offender — queries were scanning millions of rows to fetch tiny result sets.
  • Implicit conversions silently killed index usage — data type mismatches often pushed SQL Server into scans because predicates stopped being sargable.
  • Stale statistics caused bad cardinality guesses — the optimizer was building plans on data distributions that no longer reflected reality.
  • The 8 cores got split, not expanded — 4 for primary, 4 for HA replica. Freed enough budget to add redundancy without increasing licensing spend.

The database was the bottleneck, not the hardware — after tuning, even 14-year-old application servers performed fine.

What We Found

The client was running SQL Server on an Azure VM (IaaS) — 8 cores, growing frustration. The assumption was straightforward: more cores, better performance.

We spent time investigating before recommending anything. We measured CPU usage and identified the worst queries using Query Store and the plan cache — so every improvement had a baseline to compare against.

The database had three compounding problems, all fixable without touching hardware. We also checked for plan instability (parameter sniffing), spills, and parallelism misconfiguration — the usual CPU multipliers — but indexing, conversions, and maintenance were the primary issues here.

Problem 1: Missing and Wrong Indexes

Scans aren’t always wrong — but in this workload, queries were scanning huge tables to fetch tiny result sets. The difference is enormous: a scan reads every row in the table, a seek goes directly to the rows it needs.

On a table with millions of rows, a single missing index can turn a 50-millisecond seek into a multi-second scan. Multiply that across dozens of queries running concurrently, and you have a server that looks CPU-starved but is actually just doing unnecessary work.

We analyzed the workload, identified the worst offenders through execution plans and DMV queries, and added the right indexes. The scan-on-large-tables problem disappeared.

Problem 2: Implicit Conversions

This one is subtle and easy to miss.

When data types don’t match between query parameters and table columns, SQL Server performs an implicit conversion. It silently converts one type to match the other. This often pushes SQL Server into scans (or at least far more reads) because the predicate stops being sargable. A perfectly good index sits there unused because the query is sending an nvarchar parameter against a varchar column, or int against bigint, or any other mismatch.

The execution plan won’t throw an error. Look for CONVERT_IMPLICIT in the plan — that’s the tell. Your CPU pays the price quietly. Here’s our deep dive on finding and fixing implicit conversions across your codebase.

We audited their stored procedures and application queries for type mismatches, fixed them at the source, and performance jumped.

Problem 3: Stale Statistics and Neglected Maintenance

Statistics were stale — bad cardinality guesses meant the optimizer was building execution plans based on data distributions that no longer reflected reality. Some indexes showed measurable fragmentation and page density issues — increasing logical reads and I/O.

SQL Server’s optimizer is good — but it’s only as good as the information it has. Feed it stale statistics and it’ll choose bad plans confidently.

We fixed stats first, then did targeted index maintenance where it actually mattered:

  • Statistics updates on a schedule matched to their data change rate
  • Index maintenance based on actual fragmentation levels and access patterns — not a blanket “rebuild everything nightly” approach
  • Consistency checks during appropriate maintenance windows

The Result

After addressing all three issues, CPU usage dropped 20–30% on the same 8 cores. We measured before and after — same workload periods, same business cycle — so the improvement was real, not a quiet week.

That opened a conversation the client didn’t expect.

After tuning, we downsized the primary to 4 cores. That freed enough budget to add a 4-core HA replica without increasing SQL licensing spend (total monthly cost stayed roughly flat, depending on VM and storage choices).

They had redundancy they didn’t have before.

They approved immediately.

Related: How Real Workload Testing Cut Azure SQL Hyperscale Costs by 46% and Saved $86,000 a Year

Why Organizations Scale Hardware First

This pattern repeats across nearly every engagement. Performance is slow, so the request goes up for more cores, more RAM, a bigger VM.

It makes sense from an organizational perspective — infrastructure changes are faster to approve, easier to execute, and don’t require anyone to touch application code or database internals. You open a ticket, someone clicks a button, the VM gets bigger.

But it doesn’t fix the underlying problem. The same bad queries that were scanning tables on 8 cores will scan tables on 16 cores. They’ll scan faster, sure — but you’ve doubled your cloud spend to mask inefficiency.

The harder conversation is: your queries need work. Your indexing strategy needs attention. Your maintenance jobs either don’t exist or aren’t doing what you think they’re doing.

That conversation takes longer. The results last longer too.

The Hardware Question

In this case, the database was the bottleneck — not the application servers. The client’s app servers connecting to the database are 14 years old, running at 2.4 GHz. After tuning, even the old app tier was good enough.

When they eventually move to modern CPUs, they’ll have headroom to scale. But for now, the tuned database doesn’t need it.

Hardware matters — but it matters a lot less when your queries are efficient. A well-tuned database on modest hardware will outperform an untuned database on enterprise-grade infrastructure in most scenarios.

CPU Headroom After Tuning

After tuning, you want consistent headroom. If sustained CPU is consistently above 70–80% during normal peaks, you may have limited headroom for spikes or plan regressions.

If CPU is still high after tuning, either the workload genuinely needs more cores or there’s remaining optimization work to do.

After a core-count change, watch for plan changes — especially parallel plans. Don’t shotgun-recompile everything. Only recompile the few critical procedures if you see regressions, and do it in a controlled window.

Where to Start

If your SQL Server feels slow and the first instinct is “more cores”:

  1. Check for missing indexes. Look at execution plans for table scans on large tables. Query sys.dm_db_missing_index_details for the optimizer’s own recommendations — then validate them against your actual workload before creating anything.
  2. Hunt implicit conversions. Query the plan cache for plans with CONVERT_IMPLICIT warnings. Fix the data type mismatches at the application or stored procedure level.
  3. Review maintenance. Are statistics being updated? Are indexes being maintained based on actual need? On many servers we see, the answer to all three is no.
  4. Check the usual CPU multipliers. Parameter sniffing, bad MAXDOP settings, low cost threshold for parallelism, and memory grant spills. Use wait stats to identify which of these is actually hurting you. These compound with bad indexing.
  5. Measure CPU after each fix. Don’t do everything at once and hope. Fix indexing, measure. Fix conversions, measure. Fix maintenance, measure. You need to know which changes moved the needle and by how much.
  6. Then decide on hardware. If CPU is still high after tuning, you have a genuine workload that needs more resources. Scale with confidence because you know you’re not throwing hardware at bad code.

Bottom Line

The client had 8 cores and wanted more. After tuning, they needed 4 — and used the savings to add high availability.

More cores mask problems. Better indexing, correct data types, and current statistics solve them. Start with the database before you scale the infrastructure.

Frequently Asked Questions

Should I tune queries before adding more CPU cores?

Yes. Missing or poorly designed indexes, implicit conversions, and stale statistics are among the most common causes of high CPU on SQL Server. Fixing these often drops CPU usage 20–50% without any hardware change. Scale hardware after tuning confirms the workload genuinely needs more resources.

What are implicit conversions and why do they matter?

Implicit conversions happen when query parameters and table columns have mismatched data types. SQL Server silently converts one to match the other — often making the predicate non-sargable, which prevents efficient index usage. Look for CONVERT_IMPLICIT in execution plans. Fix the data types at the source to restore seek efficiency.

How do I find missing indexes in SQL Server?

Check sys.dm_db_missing_index_details for the optimizer’s recommendations. Review execution plans for table scan operators on large tables returning small result sets. Focus on the queries with the highest cumulative CPU and read counts first — those deliver the biggest improvement per fix.

What CPU utilization should I target after tuning?

There’s no universal number — it depends on your workload and latency requirements. But if you’re consistently above 70–80% during normal peaks, you have no headroom for spikes, deployments, or unexpected load. After tuning, most healthy OLTP systems run well below that during normal operation.

Can old hardware run SQL Server well after tuning?

It depends on where the bottleneck is. In this case, the database was the constraint — not the application servers. After query optimization, even 14-year-old app servers at 2.4 GHz performed fine. That won’t always be the case, but tuning eliminates database-side waste regardless of hardware age.

Speak with a SQL Expert

In just 30 minutes, we will show you how we can eliminate your SQL Server headaches and provide 
operational peace of mind

Article by
Mark Varnas
Founder | CEO | SQL Veteran
Hey, I'm Mark, one of the guys behind Red9. I make a living performance tuning SQL Servers and making them more stable.

Discover More

SQL Server Health Check SQL Server Migrations & Upgrades SQL Server Performance Tuning SQL Server Security SQL Server Tips

Discover what clients are saying about Red9

Red9 has incredible expertise both in SQL migration and performance tuning.

The biggest benefit has been performance gains and tuning associated with migrating to AWS and a newer version of SQL Server with Always On clustering. Red9 was integral to this process. The deep knowledge of MSSQL and combined experience of Red9 have been a huge asset during a difficult migration. Red9 found inefficient indexes and performance bottlenecks that improved latency by over 400%.

Rich Staats 5 stars
Rich Staats
Cloud Engineer
MetalToad

Always willing to go an extra mile

Working with Red9 DBAs has been a pleasure. They are great team players and have an expert knowledge of SQL Server database administration. And are always willing to go the extra mile to get the project done.
5 stars
Evelyn A.
Sr. Database Administrator

Boosts server health and efficiency for enhanced customer satisfaction

Since adding Red9 to the reporting and DataWarehousing team, Red9 has done a good job coming up to speed on our environments and helping ensure we continue to meet our customer's needs. Red9 has taken ownership of our servers ensuring they remain healthy by monitoring and tuning inefficient queries.
5 stars
Andrew F.
Datawarehousing Manager
See more testimonials