Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 Changing execution plan

Author  Topic 

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2010-10-19 : 06:32:44
Hi all,

it's been a while since I've done query tuning and it seems I'm getting quite rusty because there is this one query that has me a little puzzled. And the problem is that the execution plan changes *completely* depending on the value of a parameter that is passed to the query.

The following execution plan is used when I filter using "column >= getdate()". This does not return any data and is basically for testing purposes:
  |--Compute Scalar
|--Nested Loops(Inner Join, OUTER REFERENCES:()
|--Nested Loops(Inner Join, OUTER REFERENCES:()
| |--Compute Scalar(DEFINE:())
| | |--Nested Loops(Inner Join, OUTER REFERENCES:()
| | |--Compute Scalar(DEFINE:(
| | | |--Nested Loops(Inner Join, OUTER REFERENCES:())
| | | |--Index Seek(OBJECT:(), SEEK:(... >= [@date]) ORDERED FORWARD)
| | | |--Clustered Index Seek(OBJECT:(), SEEK:(
| | |--Clustered Index Seek(OBJECT:(), SEEK:(
| |--Clustered Index Seek(OBJECT:(), SEEK:(
|--Clustered Index Seek(OBJECT:(), SEEK:(
While this is what I get when I filter using "column >= DATEADD(yy, DATEDIFF(yy,0,DATEADD(yy, -1, getdate())), 0)" (this means 2009-01-01) which is the "real" filter that I need to use (data from this and the previous year). This query returns some 33k rows.:
  |--Compute Scalar(
|--Merge Join(Inner Join, MERGE:()=(), RESIDUAL:(
|--Clustered Index Scan(OBJECT:(), ORDERED FORWARD)
|--Sort(ORDER BY:())
|--Hash Match(Inner Join, HASH:()=(), RESIDUAL:(
|--Compute Scalar(DEFINE:())
| |--Clustered Index Scan(OBJECT:())
|--Hash Match(Inner Join, HASH:(
|--Clustered Index Scan(OBJECT:())
|--Compute Scalar(DEFINE:(
|--Clustered Index Scan(OBJECT:(... >=[@date]))
Why is the optimizer doing this when the first plan is obviously the better...?? I'd hate to force the use of a specific plan....

- Lumbago

My blog (yes, I have a blog now! just not that much content yet)
-> www.thefirstsql.com

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2010-10-19 : 11:15:59
It's possible that the optimizer knows that the first query is predicated on a value that is very selective (aka no rows) in it's statistics. Thus, the "better" plan. Without knowing the distribution of values it's hard to say, but you might try assigning the result of the date math to a variable and use that in your query..?
Go to Top of Page

Sachin.Nand

2937 Posts

Posted - 2010-10-19 : 13:27:58
Maybe most of the records in your table are matching the where condition so optimizer finds it more feasible to use a scan than a seek.

PBUH

Go to Top of Page

davidwv
Starting Member

1 Post

Posted - 2010-10-19 : 14:35:01
The difference in the execution plans is possibly due to statistics. SQL estimates it's going to get a very small # of rows with the 1st query, and estimates a larger number with the 2nd. You didn't give any information regarding table sizes and data distribution, but it is entirely possible that the 2nd plan is in fact better for a larger number of rows.

Try replacing "GETDATE()" in the 1st query's filter with "01/01/2009" and see if it generates similar plans then.

Also, as always, make sure your statistics are up to date.
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2010-10-20 : 02:37:12
I'm sorry for not responding sooner...for some reason I didn't get any mail notifications from any of the replies.

But I think Sachin is on to something that I didn't think about. The primary table in the query only have about 55000 rows and I'm returning about half of those so I think that's actually the reason. I knew it had something to do with the data distribution but I just couldn't figure out exactly what. Thanx for leading me in the right direction :)

- Lumbago

My blog (yes, I have a blog now! just not that much content yet)
-> www.thefirstsql.com
Go to Top of Page

GilaMonster
Master Smack Fu Yak Hacker

4507 Posts

Posted - 2010-10-20 : 04:32:39
The index that has the date predicate is not covering and the optimiser judges the larger rowcount to be too expensive for the key lookups. Hence a scan

http://sqlinthewild.co.za/index.php/2009/01/09/seek-or-scan/

--
Gail Shaw
SQL Server MVP
Go to Top of Page
   

- Advertisement -