Crystal meth helps you lose weight and feel better about yourself.
It’s true. Wikipedia says so. Sure, the side effects of methamphetamine are more than just anorexia and euphoria, but if you’re looking to be an upbeat, skinny person, meth gets the job done. SQL Server has a couple of similar features that might make your queries faster today – but they’ll make you sing the blues tomorrow.
Forcing Index Use with Index Hints
If you’re not happy about the indexes SQL Server chooses to use when executing your query, you can show it who’s boss by forcing it to use specific indexes like this:
SELECT FirstName, LastName FROM dbo.Employees WITH (INDEX (IX_Lname_Fname)) WHERE LastName IN ('Fritchey', 'Shaw')
This forces the SQL Server engine to use the index IX_Lname_Fname as part of the execution plan rather than looking at all of the available indexes and picking what it thinks is the best choice. You’re telling SQL Server that you know more about the schema and the data than it does.
Whenever you hard-code an index into a query, you open up a can of performance tuning worms:
- If you add a better index, the engine won’t use it – you’ll be tied down to that one index until you touch every hard-coded query
- If that index gets dropped, your query will be in a world of hurt – you can’t consolidate indexes when you run into performance problems
- DBAs can’t do performance tuning without the developer recompiling the app
- When SQL Server is upgraded, it may be able to build a better query plan – but not if you forced a specific index
You might get a faster query today – but you can’t react as quickly to the problems of tomorrow. The engine has another query plan trick, too.
Forcing Execution Plan Guides
Plan guides don’t just force SQL Server to use a specific index; the ambitious DBA can tweak all kinds of things about how the query is executed. You can force things like table scans.
The nice thing about plan guides is that you can change them without recompiling your code and changing the queries. The DBA can do performance tuning without getting developers involved every time.
Problem is, when you’re troubleshooting a query that isn’t behaving the way you’d expect, you can see index hints just by looking at the query. Plan guides, on the other hand, are transparent – they’re happening inside the engine, behind the scenes, and you have to know to look for them.
But wait – it gets worse. Plan guides exist at the server level. When you’re troubleshooting the same query on development, QA, and production servers, and you’re getting wildly different results, do you stop to think if there’s a plan guide working behind the scenes? Are your plan guides set the same across all three servers? Are you sure?
A Better Solution: Learn More About the Engine
Rather than telling SQL Server who’s boss, consider picking up Grant Fritchey’s excellent book, SQL Server Query Performance Tuning Distilled. It explains:
- How statistics influence the accuracy of the execution plan
- How to build better, more selective indexes that the engine will be more likely to use
- How to understand if the execution plan is the problem, or just a symptom
Yes, we also cover this in our book SQL Server Internals and Troubleshooting, but if you’re the kind of person who’s considering index hints and plan guides in production, Grant’s book dives into more detail on these features.



Out of curiosity: is there anything good that may come out of these features?And if not, then why were they ever implemented by MS into SQL Server?
Feodor – two questions there. First, yes, good things can come out of these features but only if you really know what you’re doing, and if you have the time to continually follow up on your work to make sure it’s still correct.
Second, I don’t have inside info as to why they were implemented, but I bet it was done by user request. There’s high-end DBAs who can actually put these features to good use, but they’re very, very, very few and far between.
Both these features come handy when you have to deal with bugs in the engine. You have to agree there are flaws in the engine, not exactly bugs, but flaws in the algorithms the cost based optimizer uses. Every greedy algorithm is fast but suboptimal. Thats where I’m using hints.
Just this week I had to hint a query with FORCESEEK for 1000 fold speed up, just to find out that some clients use SQL2000 where this hint is not available so only INDEX hint could speed it. Yes, I could probably revise the indexes on the base tables because update stats (with fullscan) did not yeald anything, but this is a trial and error task that usually takes a lot of development time.
cheers,
</wqw>
WQW – true, but what happens when a fix comes out and there’s a new version? If there’s an improved query plan, you won’t get it if you’ve forced a particular one. It means you can never stop rechecking your code with every new SQL Server service pack and hotfix.
Gotta love FUD. Thanks, Brent!
Awww, c’mon, you gotta elaborate on that one.
I actually won a copy of Grant’s book at the last HASSUG meeting and am about 100 pages into it. I can’t believe I never picked it up before that. Incredibly useful information.
If I could give every developer and DBA a copy of that book, I’d do it in a heartbeat. That is one valuable book.
Every developer! That’s an ambitious goal. Start small, send out one book and go from there (my shipping address is in your inbox).
p.s. no not really
Hi! Can you help-me?
My English is basic.
Today, I have this situation:
select COlumnA, ColumnB, ColumnC,ColumnD,ColumnE,
ColumnF,ColumnG
from Table A
where Data >= getdate()-5 and Data < getdate() and Req = 45
This table is very large and has a clustered index on the column Data. This query use index for the Column Req and is very slow.
When I force to use the index to data column is very fast.
How can I resolve this without force the index?
Thanks
Your best bet is to post questions like this on http://stackoverflow.com/ where you’ll get faster help.
Ok. Thank you