The Max For The Minimum
I’ve written several hundred thousand times about how important memory is to SQL Server, and to most databases in general. But once you have it, how do you make the most of it?
Well, there’ll be a few posts in this series that cover different ways of doing that, but we’re gonna start with some basic ones that I see folks tinker with in all the wrong ways.
If you don’t know how to change these settings, here are some example commands. Note that the max server memory command is supplied with -1, which will throw an error.
Why? Because this is highly dependent on Local Factors©
EXEC sys.sp_configure @configname = 'show advanced options', @configvalue = 1; RECONFIGURE; EXEC sys.sp_configure @configname = 'min server memory (MB)', @configvalue = 0; RECONFIGURE; EXEC sys.sp_configure @configname = 'max server memory (MB)', @configvalue = -1; RECONFIGURE;
Let’s figure out those local factors!
First, let’s get a stupid query to see what you have things set to:
SELECT x.name, x.value_gb, x.value_in_use_gb, x.total_physical_memory_gb, percent_of_total_memory = (x.value_in_use_gb / x.total_physical_memory_gb) * 100 FROM ( SELECT c.name, value_gb = CONVERT ( bigint, c.value ) / 1024, value_in_use_gb = CONVERT ( bigint, c.value_in_use ) / 1024, dosm.total_physical_memory_gb FROM sys.configurations AS c CROSS JOIN ( SELECT total_physical_memory_gb = CEILING ( dosm.total_physical_memory_kb / 1024. / 1024. ) FROM sys.dm_os_sys_memory AS dosm ) dosm WHERE c.name IN ( N'min server memory (MB)', N'max server memory (MB)' ) ) AS x;
This will tell you what you have min and max server memory set to, what the total physical memory in the server is, and what percent of the total memory each setting is.
Now that you have those numbers in mind, let’s talk about them.
Min Server Memory
This section can be nice and short: If you have this set to a number other than zero (which is the default, don’t play with me on this one), someone either changed the wrong setting, or took all their goofy pills.
Or both. One thing leads to another, as they say.
There are some weird cases where you might see 16, which shows up on some servers running 64bit versions of SQL Server.
If you see an 8 here, that means you’ve temporarily spawned in the wrong timeline and you need to speak to your handler about being sent back to when 32bit software was acceptable.
The worst case here is having min server memory set equal to max server memory, which prevents SQL Server from using dynamic memory, and can cause all sorts of weird issues. Bottom line: don’t do it.
If the same value is specified for both min server memory and max server memory, then once the memory allocated to the SQL Server Database Engine reaches that value, the SQL Server Database Engine stops dynamically freeing and acquiring memory for the buffer pool.
If you have weird stuff going on with your server, like the plan cache throwing up constantly, queries that are struggling with memory grants, or other oddities, you should check to make sure min server memory is not set to max server memory.
Max Server Memory
Okay, let’s make this creakin’ easy, too. If the
percent_of_total_memory column is over 100% then we’re back to the goofy pills theory of database administration.
If it’s a number between 70 and 90%, you’re probably in okay shape. Any lower, and you’re probably doing something asinine like stacking SQL Server instances and we’re back to the goofy pills theory of database administration.
But look, there’s all sorts of stuff you have to think about when you set max server memory in some situations:
- Is SSAS, SSIS, or SSRS installed?
- Are you running a workload with column store and/or batch mode components?
I’ve never opened up any SS*S component, so I’m not going to tell you how much memory you should set aside for them. I also don’t want to get in the habit of giving the wrong advice, either. You should install these things on their own server where they can use their own local resources and be much less of a bother to your production workload.
The middle point is becoming more and more of an issue though. Column store indexes and Batch Mode query execution are… different about memory.
You’ll either need to over-provision memory for those workloads, or set max server memory to a lower number than you’d would usually to accommodate them.
That’s recap backwards, in case you were wondering.
Hopefully this post gives you a useful query to look at memory settings, and how they compare to the memory your SQL Server has in it.
Tomorrow, we’ll talk about Lock Pages In Memory. It’s one of my favorite settings.
Thanks for reading!
If this is the kind of SQL Server stuff you love learning about, you’ll love my training. I’m offering a 75% discount to my blog readers if you click from here. I’m also available for consulting if you just don’t have time for that and need to solve performance problems quickly.