In my last post I covered optimisation phases and we can view optimiser information by using Trace Flag 8675. The last post looked at the search(0) and search(1) phases and we saw how the optimiser improved the cost of the query by using both of the phases with the search(1) phase resulting in the better plan in terms of cost.
I mentioned in that post that the optimiser has another phase it can use, no surprise it's called search(2) also known as the full optimisation phase (yes that's the full optimisation phase of the full optimisation stage, still with me? Good!).
The full optimisation phase I suppose would normally be reserved for those beastly queries that the optimiser really has to get to work on, looking at you Entity Framework but we can force optimiser behaviour by using an undocumented trace flag 8677 which entirely skips the search(1) phase.
Now it has to be said it's undocumented for a reason, the reason is that it's really not a good idea to do this. In fact enabling this trace flag is such a bad idea that it will probably cause no end of issues with query performance...so let's do it, but before we do let me add yet again that please don't do this! Disabling optimisation features is a really bad idea, just like we did in this post - the purpose for this demo is just to show that we can, and how dangerous it can get.
Right, on with the show...
DBCC TRACEON(3604, -1);
DBCC TRACEON(8675, -1);
DBCC TRACEON(8677, -1);
As in the last post I've enabled trace flags 3604 and 8675 and this time I've also enabled trace flag 8677. I'm going to run the following query as it won't be able to use the search(0) phase as it's only using two tables and the search(0) phase requires at least three tables in the query:
SELECT * FROM Person.Person perINNER JOIN Sales.Customer cus ON cus.PersonID = per.BusinessEntityID
OPTION (RECOMPILE);
The last time we ran the query (or we can look at the estimated execution plan) the output was the following:
End of simplification, time: 0.002 net: 0.002 total: 0 net: 0.002
end exploration, tasks: 57 no total cost time: 0.001 net: 0.001 total: 0 net: 0.004
end search(1), cost: 3.99696 tasks: 211 time: 0.002 net: 0.002 total: 0 net: 0.006
End of post optimization rewrite, time: 0 net: 0 total: 0 net: 0.006
End of query plan compilation, time: 0 net: 0 total: 0 net: 0.007
This time though because we've disabled the search(1) phase we get this instead:
End of simplification, time: 0 net: 0 total: 0 net: 0
end exploration, tasks: 57 no total cost time: 0 net: 0 total: 0 net: 0.001
end search(2), cost: 3.99696 tasks: 211 time: 0.001 net: 0.001 total: 0 net: 0.002
End of post optimization rewrite, time: 0 net: 0 total: 0 net: 0.002
End of query plan compilation, time: 0 net: 0 total: 0 net: 0.003
We can see the trace flag has worked, search(1) has been skipped and instead it has used the search(2) optimisation phase and apart from a very slight difference in compilation time the result is exactly the same which is no surprise as the search(2) phase contains all the transformation rules that can be used by the optimiser.
Let's try the query that is using three tables:
No comments:
Post a Comment