CPU clock speed versus CPU core count - higher GHz, or more cores for SQL Server?

The general rule of thumb is keep the core count as low as possible, and the processor speed as high as possible. The licensing math on that proves the point at ~$7,500 USD per core for Expensive Edition.

Buying the correct hardware can pay for itself in reduced licensing costs. See Processor Selection for SQL Server by Glenn Berry. It's a great resource on how to choose a processor for SQL Server.

Once you take into consideration SQL Server's per-core licensing structure, it makes sense to always go with the fastest processor speed available, regardless of workload type, whether OLTP or analytics. Having the fastest possible core speed is never going to be a problem. Increase the core count as required, but never do that by reducing core speed.

In other words, don't think of 16 x 2.2Ghz processors being the same as 8 x 4.5Ghz processors. The cost savings of using the 2.2Ghz processors over the 4.5Ghz processors is likely to be a maximum of about $10,000 USD (for a typical Xeon-based two processor machine). Jumping from 8 cores to 16 cores with SQL Server Enterprise Edition is likely to cost over $60,000 USD in licensing fees. In other words, you might save $10,000 in hardware costs, but you'll lose an extra $50,000 in licensing.

If you decide you need a lot of parallel processing muscle, and decide you need 32 cores for the task at hand, going with the fastest cores will pay dividends in reduced processing time. Nobody will fault you for that.

Having said all that, if the choice is one CPU or more than one CPU, always go with more than one. Running SQL Server (or any DBMS) on a single CPU can cause all kinds of problems since the capability for concurrent operations is vastly limited.


Hold on hold on hold on

While the performance and licensing aspects are interesting, they're not the only aspect of a workload to consider.

One thing that can have an impact on processor choice is worker threads.

Worker Threads?

Yeah buddy! They're the things that your SQL Server will use to run your queries and do all the background stuff that it needs to do to keep things in shape.

When you run out of worker threads, you hit THREADPOOL waits

THREADPOOL?

THREADPOOL. This is one of the nastiest waits you can have on your server, along with RESOURCE_SEMAPHORE and RESOURCE_SEMAPHORE_QUERY_COMPILE. But those are memory waits, and this is a CPU question.

So back to why this is wiggity wack.

This is how SQL Server calculates worker threads:

NUTS

Notice how doubling core counts doesn't double Max Worker Threads, and you get the same number with 1 core as you do with 4 cores? The equation is: 512 + ((logical CPUs - 4) * 16)

That's a shame, because when core counts go up, clock speed usually nosedives to a generation or two back.

NUTS

Taking a look at any recent line of Intel chips will show a similar trend.

How do I know how many threads I need?

This will depend a lot on:

  • Number of Users
  • Number of parallel queries
  • Number of serial queries
  • Number of databases and data synchronization (Mirroring, AGs, backups for Log Shipping)
  • If you leave MAXDOP and CTFP at the defaults

If you're not running out of them today, you're probably okay.

But how do you know if you are?

There are good questions, and there are great questions, and lemme tell you something, that is a GREAT QUESTION.

THREADPOOL can manifest as connection issues, and you may see messages in the error log about not being able to spawn a thread.

You can also look at your server's wait stats using a free tool like sp_Blitz or sp_BlitzFirst (full disclosure, I contribute to this project).

EXEC sp_Blitz

NUTS

EXEC sp_BlitzFirst @SinceStartup = 1

NUTS

Can't I just increase Max Worker Threads?

Increasing MWT can lead to increased SOS_SCHEDULER_YIELD waits.

That's not the end of the world, but think of it like adding a buncha screaming kids to a teacher's class.

All of a sudden, it's gonna be harder for each kid to get attention.

When a process exhausts its 4ms quantum, there will potentially be more threads ahead of it waiting to get on the CPU.

Performance might feel about the same.

How can I use fewer Worker Threads?

You cruel [noun] of a [noun], those are workers with families to support! Mortgages! Dreams!

But alright, gotta respect the bottom line. You're the boss.

The easiest place to start is changing settings like MAXDOP and Cost Threshold For Parallelism from the defaults.

If you have questions about how to set those, head over here:

  • MAXDOP setting algorithm for SQL Server

  • Why Cost Threshold For Parallelism Shouldn’t Be Set To 5

After that, your job gets a lot tougher. You've gotta figure out what's using all those threads. You can sometimes do that by looking at your wait stats.

More specifically, if you've got high waits on parallelism (CXPACKET) AND high waits on locks (LCK_), then you may be running into long blocking chains involving parallel queries.

You know what stinks? While all those parallel queries are waiting to get their locks, they don't give their allocated threads back.

You can almost hear that four core VM that your admin assured you was more than enough for any workload gasping for air, huh?

Unfortunately, the type of query and index tuning you have to do to resolve that stuff is beyond the scope of the question.

Hope this helps!


Community wiki answer:

The long and the short of it is: Most workloads for SQL Server are OLTP which benefits from higher clock speeds because it is a serial operation.

Unless you're specifically designing for a massively parallel system, clock speeds will always win out. Edge cases exist but that's the 95% of the time answer. The fact that it ends up costing less is also a nice thing.