views:

66

answers:

2

I have been working on migrating some of our data from Microsoft SQL Server 2000 to 2008. Among the usual hiccups and whatnot, I’ve run across something strange. Linked below is a SQL query that returns very quickly under 2000, but takes 20 minutes under 2008. I have read quite a bit on upgrading SQL server and went down the usual paths of checking indexes, statistics, etc. before coming to the conclusion that the following statement, found in the WHERE clause, causes the execution plan for the steps that follow this statement to change dramatically:

  And (
    @bOnlyUnmatched = 0 -- offending line
    Or Not Exists(

The SQL statements and execution plans are linked below.

A coworker was able to rewrite a portion of the WHERE clause using a CASE statement, which seems to “trick” the optimizer into using a better execution plan. The version with the CASE statement is also contained in the linked archive.

I’d like to see if someone has an explanation as to why this is happening and if there may be a more elegant solution than using a CASE statement. While we can work around this specific issue, I’d like to have a broader understanding of what is happening to ensure the rest of the migration is as painless as possible.

Zip file with SQL statements and XML execution plans

Thanks in advance!

A: 

Not sure exactly. In your "Doesn't Work - Plan" the estimated and actual rows are massively different though. Do you have AUTO STATS switched on?

Martin Smith
The option to automatically update statistics for the DB's in question is turned on - is that analogous?The difference in execution plans is what I'd love some information on.
Nathanial Woolls
Yes that's what I meant. The only other thing I can think of is was could the plan have been generated first for the case @bOnlyUnmatched = 1 then when you run it with @bOnlyUnmatched = 0 the cached plan is inappropriate? I'd be interested if anyone can provide a definitive answer too!
Martin Smith
I like that idea. To be honest, while I have several years under the belt working with SQL Server, it's mostly self taught and my ability to read execution plans could definitely use some bolstering. Any insight like that is more than welcome.
Nathanial Woolls
To be honest I'm in the same boat. I'm not at the stage where I can read plans and tell you definitively that X is happening because Y. You could maybe try using "with recompile" in your stored procedure to force it to use a new plan and execute it with @bOnlyUnmatched = 0 to see if you still get the same plan.If you do then maybe edit your question with the additional info so it gets bumped and anyone that missed it first time around sees it.
Martin Smith
I actually just happened upon OPTION(RECOMPILE), but tried it with my query and it didn't help. There's an article on "parameter sniffing" and the RECOMPILE option which sounds spot on, but the suggestions don't seem to be helping: http://www.sqlmag.com/article/sql-server/-using-the-recompile-query-hint-to-solve-parameter-sniffing-problems.aspx
Nathanial Woolls
A: 

We experienced similar problems a few years back in our migration from 2000 to 2005. The error we were seeing was actually an invalid cast error. I think I found the thread here

The query optimiser has much more freedom in SQL Server >=2005. The CASE solution is probably the best route.

Joel Mansford