February 17, 2012 at 1:06 pm
I have a query:
Insert <table1>
Select tbl2.ColA,tbl3.ColB,NULL
From <table2> tbl2
Inner Join <table3> tbl3 with (NoLock)
on tbl3.ColA = tbl2.ColA
When I display the Estimated Execution Plan, I see that SQL Server is selecting an index for <table3> that does not cover the AcctNum column, and it is doing an index scan. Additionally, SQL Server displays a "Missing Index" error message that tells me I should create an index with Key Column "ColA" and Included Column "ColB".
Now this is where it gets strange and confusing...
First, there is an existing index on <table3> which has "ColA" as its Key Column and "ColB" as its Included Column. Why SQL sever is not using this index in the first place, I do not know.
Second, when I include an index hint in the query to use this existing index, I get the following message: "Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN." And, this message shows up when I do a "Display Estimated Execution Plan" AND when I try to execute the query (and I am not including an Actual Exection Plan).
Does anyone know what is going on here, and how to solve this problem?
Thank you.
February 17, 2012 at 1:16 pm
Have you tried removing NOLOCK? You really should remove nolock regardless unless there is a good reason for it. In case you have never read it, here is a great article and discussion about the usage and ramifications of nolock. http://sqlblog.com/blogs/andrew_kelly/archive/2009/04/10/how-dirty-are-your-reads.aspx
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/
February 17, 2012 at 1:23 pm
Sean,
Yes, I have tried removing the NoLock hint. It makes no difference.
February 17, 2012 at 1:25 pm
Can you post ddl including indexes for the tables?
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/
February 17, 2012 at 1:51 pm
Sean,
You can ask me specific questions about the tables and indexes that relate to this problem, but I will not publish my table and index structures on this forum for anyone and everyone and their uncle to examine. Security considerations, you understand.
February 17, 2012 at 1:57 pm
EdwinGene (2/17/2012)
Sean,You can ask me specific questions about the tables and indexes that relate to this problem, but I will not publish my table and index structures on this forum for anyone and everyone and their uncle to examine. Security considerations, you understand.
appreciate your concerns....so obfuscate....then provide as requested.
yeah..it requires effort...but so do tried and tested workable answers.
kind regards
________________________________________________________________
you can lead a user to data....but you cannot make them think
and remember....every day is a school day
February 17, 2012 at 2:00 pm
Some generic questions:
1. What SQL Server version? "select @@VERSION"
2. Are any of the tables temporary tables?
3. Since you posted psuedo code, can you reproduce it with psuedo code?
4. Have you checked for fragmentation and reorged/rebuilt and/or run stats?
5. How large is this table, and how much memory is SQL Server allowed?
February 17, 2012 at 2:08 pm
Ten,
If someone wants to look at table and index structures that tells me that they don't have a general idea of what they're looking for or where they expect to find it.
What I'm asking for is someone who has experience with this problem and can tell me what to look for and where to look for it. I don't want someone who wants to look through everything because they don't know what or where the problem is. I can do that and I can get my fellow DBA's to help me.
February 17, 2012 at 2:18 pm
His user name isn't "Ten", it's "J Livingston SQL". Seeing small differences like that which you may have overlooked is why it's sometimes helpful to provide the DDL for review. Re-check your index already on <table3> with the one that's being suggested, perhaps it's slightly different (unique vs not?).
February 17, 2012 at 2:28 pm
Brian and J,
Sorry about that. My eye stopped on the wrong line.
And, please don't confuse "Grasshopper" with inexperienced. Just because I'm new to SQL Server Central doesn't mean I'm new to SQL Server or to being a DBA.
February 17, 2012 at 2:35 pm
the DDL of the table can help us solidly determine why the index gets skipped;
for example:
one wild guess: if tbl3.ColA and tbl2.ColA in your example below are not the same data types, then an implicit conversion will be used, which requires a table scan.
having that level of detail for the issue that mirror the real problem will allow us to give solid answers and not guesses.
...
on tbl3.ColA = tbl2.ColA
Lowell
February 17, 2012 at 3:28 pm
EdwinGene (2/17/2012)
If someone wants to look at table and index structures that tells me that they don't have a general idea of what they're looking for or where they expect to find it.
That's a bad assumption to make. Most issues around exec plans and indexes are very specific to the query/structure, not general problems. I could make guesses without seeing at least the table and index designs (obfuscate the names, those don't matter. The types do) and some rough row counts, or preferably the plan itself.
What I'm asking for is someone who has experience with this problem and can tell me what to look for and where to look for it. I don't want someone who wants to look through everything because they don't know what or where the problem is. I can do that and I can get my fellow DBA's to help me.
I have a fair knowledge of indexes and execution plans, but without seeing more details I cannot tell you exactly what the problem is, I can only guess. Maybe there's only a non-sargable predicate (I don't know how far you obfuscated the query), maybe there's an implicit conversion, maybe the index is filtered, maybe there really is no predicate at all (so the entire table is necessary) and so scans are more optimal
That said, if the query is as simple as that the most likely reason for not having any seeks in this is that you have no row-limiting, sargable predicates. The only time joins cause seeks is when SQL does a nested loop join, and that requires a small number of rows in the outer table (and an appropriate index on the inner table), otherwise it'll scan both and hash or merge join. Just a guess without knowing row counts or seeing the exec plan.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
February 17, 2012 at 3:30 pm
additionally the number of rows in the table can determine if an index gets skipped. Without reproducible code to work with, it's like calling your mechanic and saying "My car broke down, it won't start. Tell me how to fix it." Then when he asks for more information you respond "obviously you don't know what your doing or you would tell me."
The above is a bit extreme, but without sample code for the tables, indexes, and number of rows in each table... who knows?
February 17, 2012 at 8:10 pm
Can you post ddl including indexes for the tables?
February 21, 2012 at 10:46 am
Gail,
Thank you for your suggestions. Your suggestion about sargable predicates has helped me to find an alternate way to invoke the query to get SQL Server to use the correct index.
Using the query as it was I was finally able to get SQL Server to use the correct index by inserting a Where clause that limited tbl3.ColA to a single value (Where tbl3.ColA = 'value'). Of course, this obviously would not return the result I was trying to get, but it got me thinking along the path which led to a workable solution (in this case).
I tried to come up with a way that I could limit tbl3.ColA with a Where clause, but I just couldn't find a way that would do that and still include all of the values (which could change) from <table2>. Selecting all the values from <table2> and using the In() function didn't work. Even selecting the max value from <table2> and using that in a Where clause (Where tbl2.ColA <= MaxValue) didn't work.
Then it dawned on me that a way to restrict tbl3.ColA to one value would be to use a Cursor and Dynamic SQL. I know - it didn't seem right to me either. However, given that I had stopped the original query test after 15 minutes and that <table2> is very small (just over 1500 rows) and that it would be using the correct index in <table3>, I figured WTF, I'll give it a try.
The Query is now returning a result set in three (count 'em: THREE) seconds, as compared to somewhere north of 15 minutes for the original query.
So, you see, this is why I wanted a response from someone who has seen this before or who has experience in this area. Your "guess", based on your experience, was just what I asked for and just what I needed to enable me to find a solution. And, you didn't need to see my table or index structures to do it.
Thank you very much for your help. This was much more valuable to me than having a solution spelled out for me. Give a man a fish and he eats for one day. Teach a man to fish, and he eats for the rest of his life.
Viewing 15 posts - 1 through 15 (of 20 total)
You must be logged in to reply to this topic. Login to reply