More undocumented ways to explore how the query optimizer works.
About This Blog
Saturday, 31 July 2010
Inside the Optimizer: Constructing a Plan – Part 4
Inside the Optimizer: Constructing a Plan – Part 3
Presenting an undocumented Dynamic Management View we can use to identify the optimization rules involved in producing an executable plan.
Thursday, 29 July 2010
Inside the Optimizer: Constructing a Plan - Part 2
Continuing the series of posts looking at how the optimizer matches and applies internal rules to refine a query plan.
The last post ended with this query plan:
The optimizer has pushed the predicate ProductNumber LIKE 'T%'
down from a Filter to the Index Scan on the Product
table, but it remains as a residual predicate.
Inside the Optimizer: Constructing a Plan - Part 1
For today’s entry, I thought we might take a look at how the optimizer builds an executable plan using rules. To illustrate the process performed by the optimizer, we will configure it to produce incrementally better plans by progressively applying the necessary rules.
Wednesday, 28 July 2010
Ranking Function Optimizer Transformations
In my last post I showed how SQL Server 2005 and later can use a Segment Spool to implement aggregate window functions and the NTILE
ranking function.
The query optimizer is also smart enough to recognise that some queries are logically equivalent to a window function, even if they are written using different syntax.
Partitioning and the Common Subexpression Spool
SQL Server 2005 introduced the OVER
clause to enable partitioning of rowsets before applying a window function. This post looks at how this feature may require a query plan containing a ‘common subexpression spool’. This query plan construction is required whenever an aggregate window function or the NTILE
ranking window function is used.
The Segment and Sequence Project Iterators
In my last post I promised to cover the Segment iterator in more detail, so here we go.
Segment
The Segment iterator partitions rows into groups as they flow through a query plan, checking whether the current row belongs in the same group as the previous row. For this to work, the incoming rows must be presented in an order which guarantees that all members of a group are received sequentially.
Segment has a “Group By” argument to specify how it should partition its input. The iterator adds an additional column to the rows that flow through it. This new column is used to communicate with its parent iterator, and is named something like [Segment1003]
.
The new column is visible in the graphical query plan properties window, or by hovering your mouse cursor over the Segment operator. The attribute name in both cases is Segment Column
).
The “Segment Top” Query Optimization
A question that often comes up on the forums is how to get the first or last row from each group of records in a table. This post describes a clever query plan optimisation that SQL Server can use for these types of query.