Perhaps this is more of a misconception than a tip. Nevertheless, it was something that tripped me up the first time I used SQL server, and I’ve gotten asked about high memory utilization by SQL server quite few times by others.
Often times, after use, if you go in Task Manager, you’ll notice that SQL Server’s memory footprint has grown to take up most of the free memory on a machine. In many scenarios for application developers, this triggers the thought “memory leak”. Well, in this case it isn’t.
SQL server expands to use up all the memory it can on the server. It will continually poll the server to determine if more free memory is needed for other programs and will relinquish it so as not to starve them. SQL server relies more on itself for memory management than underlying OS.
In the end, if the company paid for all that RAM on your SQL box, why not use it all?
Of course these options are configurable. This can be done by using the sp_configure stored procedure with the “max server memory” and “min server memory” options.
On a dedicated SQL box, I’ll set the max server memory to the size of the RAM available on the box minus 1 to 2 gigabytes. This gives some extra cushion for the OS even though it is not necessary.
Here’s an article listing the options that are available for sp_configure. http://msdn.microsoft.com/en-us/library/ms189631.aspx
Here’s a great article to read to get up to speed on SQL server and it’s memory usage and some different options to take into consideration when setting it up. http://msdn.microsoft.com/en-us/library/ms178067.aspx
The other day, I ran across the resource governor in SQL server. It looked great. I was testing some queries that were abusing parallelism. The queries in question executed as a parellel plan but ended up hanging on a CXPACKET wait type. (See my previous posts on wait stats). As such, parallelism was not gaining the benefits.
The queries were able to be re-written to avoid this, but I also investigated some alternative options as well.
First, without doing much modification, it’s easy to eliminate parallelism in an executing query, using the OPTION (MAXDOP 1) clause. Putting this at the end of the query will eliminate SQL server from using parallelism when it compiles the plan. This is a good alternative when the query just can’t quite be re-written in a way where SQL server avoids parallelism.
Another way to eliminate parallelism is to use the server wide setting “max degree of parallelism”. However, since this is a server wide setting, it will eliminate parallelism in most cases. Applying this server wide seems like overkill as certain queries may perform better with a parallel plan.
The third option I found actually turned out to not work at all. This was to set up a resource pool in resource governor which limited the MAXDOP setting for a specific user. The user was set up in the database and running all of the queries which were in question. After doing some preliminary research the option looked promising, but after doing some query tests, the query actually performed worse. The MAXDOP option in the resource governor doesn’t behave the same way. The first two options are taken into account during compilation of a query, while the MAXDOP option in the resource governor is not. Once the setting is set, it doesn’t eliminate parallelism from the query plan, it just limits the number of processors that can be used in a parallel plan. It seems misleading since they have the same name.
This article describes the option well: http://msdn.microsoft.com/en-us/library/ms188611(v=SQL.105).aspx
Just remember MAXDOP is not always the same as MAXDOP!