
Well I am getting older but we aren’t going to talk about that! And hopefully your memory hasn’t gone for a swim like the picture to the left, I can’t help with that. So what am I talking about? Well it seems that I get asked some variance of this question a couple of times each week. Generally speaking there are two variations of the question and I will address the first question in part 1 of this two part series.
Question #1 – Why is SQL Server using all of the available memory?
The answer to this one is pretty simple. SQL Server is incredibly memory hungry! SQL has its own memory manager and will try and grab as much memory as it can, even to the point of starving the OS or other processes that dare run on the same hardware.
So that brings us to the follow-up question I hear, “Well then why is it using all of the memory even during non-peak times?” Again this is a pretty quick answer. Once SQL Server allocates its memory resources it is loath to give them up. After all what could possibly be more important than SQL caching every bit of data it can? (Pun intended
) On a more serious side it takes resources and time to allocate the memory and if SQL needed the memory once, it will probably need it again. In the end it’s just a matter of efficiency to let SQL Server hang on to the memory and allocate it how it sees fit.
Finally we need to address how we limit SQL Server’s lust for memory. Luckily Microsoft has given us two configuration options for doing just that. The first and IMHO most important is max server memory. By default max server memory is set to 2147483647 Megabytes! Now obviously this max setting is a bit of a dream and is not ideal. Generally speaking if the server is dedicated to the sql engine and has 16GB or less of ram then I set max server memory to the amount of physical ram minus 2GB. So if the server has 16GB then I will configure max server memory to 14GB. If the server has more than 16GB then I typically use the amount of physical ram minus 4GB. So if the server has 64GB of ram I would set a max of 60GB. If the server is not dedicated to the sql engine then make sure you take those other features and programs into account. Leave plenty of room for the others so everyone can get along and play nice together.
One thing that I have noticed is that the more ram you have, it seems the more you need to leave available. This phenomenon can be explained by a quirk you should keep in the back of your mind. Unlike what the setting name implies, know that max server memory does not limit the entire sql process; it only limits the buffer pool. So don’t be surprised if you look at the SQL Server process and notice it is using more than the max limit you set. Generally the more ram you have, the more processors you will also have, which means more threads are allocated by default and each of those threads is using memory outside the buffer pool. In addition if you like to use linked servers, SQL CLR, and other features they will get their memory from outside the buffer pool.
So now that you have done some quick calculations in your head, here is how you configure the max server memory using TSQL.
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
--set the max to 4GB
sp_configure 'max server memory', 4096;
GO
RECONFIGURE;
GO
The second setting available to us is minimum server memory. Generally speaking I don’t mess with this much. Typically the only time I do is if there are multiple instances of sql running on the same server. However there are other schools of thought that say you should set the min server memory setting to the same amount as max server memory. Either way it does pay to understand the behavior of the setting so that you can make your own informed decision.
Should the server experience memory pressure, sql server will either decide on its own to give up memory or it will be forced to do so. The min server memory option allows us to specify a minimum amount of memory sql will not go below. Again this setting is only enforced for the buffer pool and has its own quirks. Many people mistakenly believe that this setting means sql will grab at least this much memory and never drop below it. However sql does not grab the minimum amount until it is actually needed. So if sql never goes above the minimum then the minimum will not apply.
Once you have made your decision, this is how you configure the min server memory setting using TSQL.
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
--set the min to 1GB
sp_configure 'min server memory', 1024;
GO
RECONFIGURE;
GO
*Edited: Here is the link to part 2.
best practices, configuration options, performance tuning, server memory