|
Basic SOURCE Table defns:
(tried it without "unique" nonclustered indices, doesn't help)
QUERY plan says that it will use indexes: IX_1 and IX_2 (Index Scan) to fullfil the query. Since "catid" is not even mentioned in the query, why has it chosen a scan of an index rather than the direct route to the actual record? Why not a "Clustered Index SEEK" ? Use of the non-clustered indexes causes an error (Conversion failed when converting the nvarchar value "some string" to data type int). Of course, if it had used the PK, there would be no conversion issue. Adding the resultant query plan:
(comments are locked)
|
|
The Execution Plan in Microsoft SQL Server is cost based. It is cheaper for the Storage Engine to scan a table (sequential reads) than seek a table (random reads). In your case, it depends on what more columns are fetched from the query. The Storage Engine will avoid to do Key Lookups if possible. Also, since there is no SARG-able filter clause in your query, a SEEK can never happen since you basically told the Storage Engine to fetch all records. Thanks, this explains it well.
Oct 21 '09 at 04:13 PM
Andrew
(comments are locked)
|
You've misread the code to some extent. No unanticipated rows would ever be returned - "lookup_val1 & 2" reference the PK of the "lkup" table (1-to-1 join). (BINT and CATID are not relevant for this query - i'm providing the "lkup" PK value via "lookup_val1 & 2"). I accept the table scan on "table_L" - it's what I required. What I don't like, is that the "lkup" table is preferring to scan non-clustered indexes rather than performing a clustered index SEEK. Pt 2, 3 & 5 - I agree with. Pt 4 - no exceptions, lookup_val1 & 2 will always have values.
Oct 21 '09 at 04:04 PM
Andrew
You're correct, I did misread the reference to the primary key of the LKUP table. My apologies. That error certainly makes number 4 off the mark, although it had nothing to do with the presence or absence of values. However, the fact remains that SQL is being asked to perform two joins that will include every row in the primary table. According to the optimizer's calculations, based on the volumes and statistics known to it, it can scan the indexes and do hash matches faster than it can do a number of discrete SEEKS.
Oct 22 '09 at 12:25 AM
Bob Hovious
Two things to try:
Please let me know what the results are.
Oct 22 '09 at 12:26 AM
Bob Hovious
(comments are locked)
|
|
The conversion error is not caused by the use of the index. It's your cast that's the issue there. Why are you even bothering to cast the values in the SELECT statement? If they are numeric in nature, though stored as strings (why), they'll return just fine. Since it's doing a scan, it probably sees fewer pages in each of those indexes so it's trying to save time by scanning them rather than scanning the table/clustered index which probably has more pages in it. Pt 2 is probably correct as far as the optimizer is concerned - granted. Pt 1 - the "lkup" table is a lookup table, so certain "catid" will contain non-numeric values, and others, numeric values. My expectations for these items are that they will be numeric - always. The conversion error occurs, because it is returning records that do not correspond to the "ON" clause ... the "cast" is occuring prior to the "filtering" of the resultant set.
Oct 21 '09 at 03:12 PM
Andrew
Since it's doing a scan on these indexes, it's very likely that you're getting a CAST before the data comes back.
Oct 21 '09 at 08:18 PM
Grant Fritchey ♦♦
(comments are locked)
|
|
Also, regardless of index strategy, you're asking for a I'm not ... the angst is that the PK is not used to obtain the exact record requested - which would never contain non-numerics.
Oct 21 '09 at 03:08 PM
Andrew
(comments are locked)
|

