Supplements and SQL Hints - Part 1 - TSQL Helpers
Let's face it, every now and then we need some help. A little boost to get over the finish line. Whether that be in the gym or in your daily life as a database administrator. Hence I am putting together a little mini series: Supplements and SQL Hints! Both are little helpers that can assist in crossing the finish line of a goal or simply improving overall performance. Honestly, when I first conceived of The Viking DBA Blog, this was I believe the second topic I jotted down to write about. Just never got around to it. But we're here now so let's dive in.
Week 2 - Pre-workout supplements and energy boosters
Week 3 - Table Hints. These are elements you can apply at a single table level
Week 4 - Post workout supplements and muscle builders
Week 5 - Join Hints. You guessed, how to affect your join operators
OPTION (Recompile)
Example:
Why would you use this hint? The first time a query runs, the SQL engine will first check to see if it has a cached (stored) execution plan that matches the query to be executed. If it does, excellent. It chooses that plan and uses it. That sounds efficient right? In the case of my example above query, this particular one probably doesn't need a recompile. Even though a different value might be passed in the parameter each time, since it's only seeking one record and in this case it's the ID, it should be lightening fast and the cached execution plan is fine.
However, let's change that query up a little and try by name instead. For the purposes of this example, my Customers table is 121 distinct customer name records and 100,000 with BrianM. This is all very rudimentary, but hopefully you'll get the idea.
Even though I do have an index on the CustomerName field, because of the skewed data where every other record has just one value but 'BrianM' has 100,000, the engine is guessing based on the statistics it'll find more. When in reality it's found just one.
So now with our cached plan, let's pass in the 'BrianM' value and see what happens.
Whoa! What happened to our estimates? The cached plan thought it was going to find 821 but got 100,000 instead! You might ask, what's the big deal? Incorrect estimates such as this will lead to memory grant issues, spills to TempDB and single threaded operations to name a few. The cached plan was granted X amount of memory, but when we passed the different parameter value, that memory may not be enough. SQL only allocates what it though it needed at the time of execution. Which would then lead to TempDb spills. Essentially keeping the data in TempDb until it's needed in the next step or the end. Also, in a previous blog post I address the Cost Threshold for Parallelism. If the first plan isn't very large, it won't hit that cost threshold and it'll only utilize one core. Start passing in larger ranges of parameter values and suddenly the query is gasping for more CPU.
OPTION Recompile addresses this problem. Adding that in, the engine will rebuild the execution plan every time it runs so as to maximize efficiency for the values coming. Think about something such as an Orders table. Pass in order date range of a single day, it returns results quickly. You want a whole month? Now you wait and wait and wait.... If the query or procedure had an OPTION recompile on there, it can build the plan according to the different values.
OPTIMIZE FOR ( (@parameter=value))
Now we can see the estimate as being 50,000 records. Because I told the execution to build as if the parameter value would be 'VikingDBA'.
OPTION (MAXDOP x)
With this option, you override the configured value at the server level and for this specific query tell it how much processor power it can use. Got a query that might need a little extra horsepower? Drop this option in and temporarily use however many processors you feel comfortable with. This is not one I would personally tinker with too much. The server level settings are typically sufficient. However, in that rare case, just know you have it in the toolbelt.

Comments
Post a Comment