Ich weiß, dass dies aus Leistungsgründen vermieden werden sollte, aber ich versuche, einen Zustand zu zeigen, in dem es als Demo angezeigt wird, um sicherzustellen, dass es nicht angezeigt wird.
Ich erhalte jedoch eine fehlende Indexwarnung, doch das Optimierungsprogramm erstellt keinen temporären Index.
Die Abfrage, die ich verwende, ist
SELECT
z.a
FROM dbo.t5 AS z WITH(INDEX(0))
WHERE
EXISTS
(
SELECT y.a
FROM dbo.t4 AS y
WHERE y.a = z.a
)
OPTION (MAXDOP 1);
Tabellenschemata sind:
CREATE TABLE dbo.t4
(
a integer NULL,
b varchar(1000) NULL,
p varchar(100) NULL
);
CREATE TABLE dbo.t5
(
a integer NULL,
b varchar(1000) NULL
);
CREATE UNIQUE CLUSTERED INDEX c1
ON dbo.t5 (a);
Beide Tabellen haben 10.000 Zeilen, mit denen Sie simulieren können:
UPDATE STATISTICS dbo.t4
WITH
ROWCOUNT = 10000,
PAGECOUNT = 1000;
UPDATE STATISTICS dbo.t5
WITH
ROWCOUNT = 10000,
PAGECOUNT = 1000;
Der Abfrageplan lautet:
<?xml version="1.0" encoding="utf-16"?>
<ShowPlanXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.2" Build="11.0.2218.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementCompId="1" StatementEstRows="5532.16" StatementId="1" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" StatementSubTreeCost="0.407384" StatementText="select a from t5 z WITH(INDEX(0)) where exists (select a from t4 where a=z.a )" StatementType="SELECT" QueryHash="0x1B882FCEA34AEAF4" QueryPlanHash="0x1B276DC04B718F7C" RetrievedFromCache="true">
<StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" />
<QueryPlan DegreeOfParallelism="1" MemoryGrant="2912" CachedPlanSize="32" CompileTime="10" CompileCPU="10" CompileMemory="296">
<MissingIndexes>
<MissingIndexGroup Impact="82.4536">
<MissingIndex Database="[planoper]" Schema="[dbo]" Table="[t4]">
<ColumnGroup Usage="EQUALITY">
<Column Name="[a]" ColumnId="1" />
</ColumnGroup>
</MissingIndex>
</MissingIndexGroup>
</MissingIndexes>
<MemoryGrantInfo SerialRequiredMemory="1024" SerialDesiredMemory="2912" RequiredMemory="1024" DesiredMemory="2912" RequestedMemory="2912" GrantWaitTime="0" GrantedMemory="2912" MaxUsedMemory="896" />
<OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="104846" EstimatedPagesCached="11834" EstimatedAvailableDegreeOfParallelism="2" />
<RelOp AvgRowSize="11" EstimateCPU="0.228447" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="5532.16" LogicalOp="Left Semi Join" NodeId="0" Parallel="false" PhysicalOp="Hash Match" EstimatedTotalSubtreeCost="0.407384">
<OutputList>
<ColumnReference Database="[planoper]" Schema="[dbo]" Table="[t5]" Alias="[z]" Column="a" />
</OutputList>
<MemoryFractions Input="1" Output="1" />
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="10000" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<Hash>
<DefinedValues />
<HashKeysBuild>
<ColumnReference Database="[planoper]" Schema="[dbo]" Table="[t5]" Alias="[z]" Column="a" />
</HashKeysBuild>
<HashKeysProbe>
<ColumnReference Database="[planoper]" Schema="[dbo]" Table="[t4]" Column="a" />
</HashKeysProbe>
<ProbeResidual>
<ScalarOperator ScalarString="[planoper].[dbo].[t4].[a]=[planoper].[dbo].[t5].[a] as [z].[a]">
<Compare CompareOp="EQ">
<ScalarOperator>
<Identifier>
<ColumnReference Database="[planoper]" Schema="[dbo]" Table="[t4]" Column="a" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Database="[planoper]" Schema="[dbo]" Table="[t5]" Alias="[z]" Column="a" />
</Identifier>
</ScalarOperator>
</Compare>
</ScalarOperator>
</ProbeResidual>
<RelOp AvgRowSize="11" EstimateCPU="0.0110785" EstimateIO="0.0565368" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="10000" LogicalOp="Clustered Index Scan" NodeId="1" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="0.0676153" TableCardinality="10000">
<OutputList>
<ColumnReference Database="[planoper]" Schema="[dbo]" Table="[t5]" Alias="[z]" Column="a" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="10000" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<IndexScan Ordered="false" ForcedIndex="true" ForceScan="false" NoExpandHint="false">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[planoper]" Schema="[dbo]" Table="[t5]" Alias="[z]" Column="a" />
</DefinedValue>
</DefinedValues>
<Object Database="[planoper]" Schema="[dbo]" Table="[t5]" Index="[c1]" Alias="[z]" IndexKind="Clustered" />
</IndexScan>
</RelOp>
<RelOp AvgRowSize="11" EstimateCPU="0.011157" EstimateIO="0.100162" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="10000" LogicalOp="Table Scan" NodeId="2" Parallel="false" PhysicalOp="Table Scan" EstimatedTotalSubtreeCost="0.111319" TableCardinality="10000">
<OutputList>
<ColumnReference Database="[planoper]" Schema="[dbo]" Table="[t4]" Column="a" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="10000" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<TableScan Ordered="false" ForcedIndex="false" ForceScan="false" NoExpandHint="false">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[planoper]" Schema="[dbo]" Table="[t4]" Column="a" />
</DefinedValue>
</DefinedValues>
<Object Database="[planoper]" Schema="[dbo]" Table="[t4]" IndexKind="Heap" />
</TableScan>
</RelOp>
</Hash>
</RelOp>
</QueryPlan>
</StmtSimple>
</Statements>
</Batch>
</BatchSequence>
</ShowPlanXML>
Es sagt mir sogar, dass ich diesen Index erstellen soll:
USE [planoper];
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[t4] ([a]);
Antworten:
Eine Möglichkeit, eine Index-Spool auf natürliche Weise anzuzeigen, besteht darin, die Anforderung in einer etwas anderen Syntax auszudrücken:
Dies erzeugt einen Ausführungsplan wie:
Das Umschreiben der Gleichheit in ein Paar äquivalenter Ungleichungen fördert die Verwendung einer Index-Spool, obwohl das gespoolte Prädikat nicht genau das ist, wonach Sie gesucht haben, die Semantik ist letztendlich die gleiche.
Es gibt keine einfache Möglichkeit, die gewünschte Index-Spool mithilfe der ursprünglichen Syntax einzuführen. Das heißt jedoch nicht, dass es unmöglich ist. Da Sie dies nur für eine Demo benötigen und dies nicht in der Nähe eines Produktionssystems verwenden , zeige ich Ihnen einen anderen Weg:
Der Ausführungsplan lautet:
Das Index-Spool-Prädikat ist wie gewünscht:
Sie können diesen Plan nicht in einem
USE PLAN
Hinweis verwenden, da das Optimierungsprogramm ihn normalerweise nicht berücksichtigt.Weitere Lektüre:
quelle