SQL Server Forced Plans Overwite the Query Hash
Plan Forcing Overwrites the Query Hash
If you âforceâ a plan (using any method, including Plan Guides, Query Store, and Automatic Plan Correction) the resulting plan will have its query_hash
overwitten by the query_plan_hash
.
In other words, the plan hash and query plan hash will be given the query plan hash value. The real query hash value is simply lost. đ€Šââïž
This will break anything you have that uses query_hash
for any purpose, including scripts and tools.
Example
One example way to reproduce this:
- Create a table.
- Select from it, capturing the execution plan.
- Copy the XML showplan for the select.
- Run the select again with the showplan XML in a
USE PLAN
hint.
Code:
DROP TABLE IF EXISTS dbo.T1;
CREATE TABLE dbo.T1 (c1 integer NOT NULL);
GO
SELECT c1
FROM dbo.T1
OPTION (USE PLAN N'<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.564" Build="16.0.4165.4"><BatchSequence><Batch><Statements><StmtSimple StatementText="SELECT c1 
FROM dbo.T1" StatementId="1" StatementCompId="1" StatementType="SELECT" RetrievedFromCache="true" StatementSubTreeCost="0.0032831" StatementEstRows="1" SecurityPolicyApplied="false" StatementOptmLevel="TRIVIAL" QueryHash="0x31B14566F8F8A256" QueryPlanHash="0x10D77A8E4F35F994" CardinalityEstimationModelVersion="160"><StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false"></StatementSetOptions><QueryPlan CachedPlanSize="16" CompileTime="0" CompileCPU="0" CompileMemory="80"><MemoryGrantInfo SerialRequiredMemory="0" SerialDesiredMemory="0" GrantedMemory="0" MaxUsedMemory="0"></MemoryGrantInfo><OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="104857" EstimatedPagesCached="104857" EstimatedAvailableDegreeOfParallelism="8" MaxCompileMemory="12103680"></OptimizerHardwareDependentProperties><RelOp NodeId="0" PhysicalOp="Table Scan" LogicalOp="Table Scan" EstimateRows="1" EstimatedRowsRead="1" EstimateIO="0.0032035" EstimateCPU="7.96e-05" AvgRowSize="11" EstimatedTotalSubtreeCost="0.0032831" TableCardinality="0" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row"><OutputList><ColumnReference Database="" Schema="[dbo]" Table="[T1]" Column="c1"></ColumnReference></OutputList><TableScan Ordered="0" ForcedIndex="0" ForceScan="0" NoExpandHint="0" Storage="RowStore"><DefinedValues><DefinedValue><ColumnReference Database="" Schema="[dbo]" Table="[T1]" Column="c1"></ColumnReference></DefinedValue></DefinedValues><Object Database="" Schema="[dbo]" Table="[T1]" IndexKind="Heap" Storage="RowStore"></Object></TableScan></RelOp></QueryPlan></StmtSimple></Statements></Batch></BatchSequence></ShowPlanXML>');
The âforcedâ execution plan has identical query_hash
and query_plan_hash
values:
QueryHash="0x10D77A8E4F35F994"
QueryPlanHash="0x10D77A8E4F35F994"
Notice the identical hashes.
Impact
This bug affects SQL Server 2008 to 2022 CU16 inclusive.
Until Microsoft fix this (and backport it to 2008 đ€Ł) any plans subject to âforcingâ will have an incorrect query hash. đ„ł
Note: Only guided plan search is affected. Supplying individual query hints (except USE PLAN
of course) in a plan guide (or via an equivalent feature) does not provoke this misbehaviour.
I first remember seeing this type of behaviour publicly reported in a series of posts by @sqL_handle, in a post on đ by TomĂĄĆĄ ZĂka, and most recently in a blog post by Kendra Little.
âMorally Equivalentâ Plans
On a related point, there seems to be some confusion around the meaning of a âmorally equivalentâ execution planâa term coined by Conor Cunningham from the Microsoft query optimizer team. It can be a useful shorthand term, but only if you understand what it is shorthand for.
When you âforceâ an execution plan, the plan produced may not exactly match the template. The intention is for the produced plan to be very similar to the guide plan.
Microsoft acknowledge this in the documentation (emphasis added):
The resulting execution plan forced by this feature will be the same or similar to the plan being forced. Because the resulting plan may not be identical to the plan specified by the plan guide, the performance of the plans may vary. In rare cases, the performance difference may be significant and negative; in that case, the administrator must remove the forced plan.
Guides, not rules
The term âplan guideâ is rather more technically accurate than âforced planâ.
The XML representation of a plan is used to guide the query optimizer through its normal optimization process. The XML is parsed into a âhint treeâ with a similar shape as the internal tree of logical operators formed by parsing and transforming the original T-SQL statement into a form the query processor finds convenient to work with.
The hint tree guides the query optimizer as it progresses through its normal cost-based optimization search. For clarity, these are not T-SQL hints; SQL Server uses the shape, properties, and node types in the hint tree to guide the search.
Guided search
Well, not quite normal search because all optimizer features are enabled in case they are needed to reach the goal. In older versions of SQL Server, this meant a guided plan search always went straight into the search 2
(full optimization) strategy. In recent versions, accelerated plan forcing allows guided search in search 1
.
Working top down, any transformation or optimization that could notâor does notâproduce the output described by the matching hint tree node is discarded. The effect is to constrain the optimizer to exploration paths that result in the same structure as described by the hints.
Differences
SQL Server uses the supplied XML representation as a guide rather than a strict template for several reasons.
- Showplan XMLâlike any textual plan representationâis not a complete description of the internal executable plan, which is essentially a dynamic program capable of being directly executed to produce the results and effects logically described by the T-SQL statement. In other words, there simply isnât enough information in the source to directly produce an executable plan.
- Following the optimizerâs usual paths ensures the output is a plan the optimizer could have produced naturally. It is therefore guaranteed to respect all the logical semantics of the source T-SQL.
- Allowing a user or program to submit arbitrary executables described by XML could open the way to security problems or undefined behaviour at the server.
All this means the plan eventually selected by the optimizer will often not match the guide plan exactly. It is intended to match all the important aspects captured in the XML, but the implementation is not exhaustive even given the limited source detail available. For example, the guiding process does not currently consider nested loops prefetching as an important property to match.
Reasons
Some of the implementation coverage shortfall is due to inherent limitations of the optimization framework. For example, the exact position of filters and compute scalars cannot be specified for architectural reasons.
Many other limitations exist. Some could be addressed fairly easily in principle, but you have to remember Microsoft is a small company with a limited budget and important features like Big Data Clusters to work on instead.
Effects
The plan produced via the guiding process will be visually very similar to the supplied XML plan. It may differ in details considered less important or simply not captured in the XML representation.
Since the output fingerprint of the final plan (query_plan_hash
) depends on all the executable plan details (including many not visible to users in any form), the finished plan will often have a different query_plan_hash
from the original. The input fingerprint based on the input logical tree (query_hash
) will, however, be the same (bugs aside).
Finishing up
The term âmorally equivalentâ is intended to capture many of the nuances above. I donât know how successful it is, or what morals have to do with anything, but there we are.
A plan guide can produce plans with minor variations compared with the source plan. Sometimes, these âminor variationsâ can have large performance impacts. There was a time when Microsoft were interested in hearing about such cases. I have no idea if thatâs still true.
Thanks for reading.