Verwenden des USE PLAN-Abfragehinweises
Der USE PLAN-Abfragehinweis nimmt xml_plan als Argument an. xml_plan ist ein Zeichenfolgenliteral, das von dem als XML formatierten Abfrageplan abgeleitet wird, der für die Abfrage erstellt wird. Der USE PLAN-Abfragehinweis kann als Abfragehinweis in einer eigenständigen SQL-Anweisung oder im @hints-Parameter einer Planhinweisliste angegeben werden. Um einen Abfrageplan an eine Planhinweisliste anzufügen, verwenden Sie vorzugsweise den xml_showplan-Parameter in der gespeicherten Prozedur sp_create_plan_guide bzw. sp_create_plan_guide_from_handle.
Wichtig |
---|
Sie sollten xml_plan immer als Unicode-Literal angeben, indem Sie das Präfix N angeben (wie z. B. in N'xml_plan'). Auf diese Weise wird sichergestellt, dass keine Zeichen im Plan, die für den Unicode-Standard spezifisch sind, verloren gehen, wenn SQL Server Database Engine (Datenbankmodul) die Zeichenfolge interpretiert. |
In SQL Server können als XML formatierte Abfragepläne auf die folgende Weise erstellt werden:
-
Wichtig Wenn Sie Abfragepläne mithilfe von SET SHOWPLAN_XML generieren, müssen Anführungszeichen ('), die im Plan enthalten sind, durch ein zweites Anführungszeichen geschützt werden, bevor der Plan mit dem USE PLAN-Abfragehinweis verwendet werden kann. Ein Plan, der WHERE A.varchar = 'This is a string' enthält, muss z. B. geschützt werden, indem der Code in WHERE A.varchar = ''This is a string'' geändert wird.
Durch Abfragen der Spalte query_plan in der dynamischen sys.dm_exec_query_plan-Verwaltungsfunktion.
Mit den SQL Server Profiler-Ereignisklassen Showplan XML, Showplan XML Statistics Profile und Showplan XML For Query Compile.
Weitere Informationen zum Erstellen und Analysieren von Abfrageplänen finden Sie unter Analysieren einer Abfrage.
Der in xml_plan angegebene, als XML formatierte Abfrageplan muss anhand des XSD-Schemas Showplanxml.xsd im Installationsverzeichnis von SQL Server überprüft werden. Außerdem muss unter dem Pfad, der die <ShowPlanXML> <BatchSequence> <Batch> <Statements>-Elemente enthält, eines der folgenden Elemente angezeigt werden:
Ein oder mehrere <StmtSimple>-Elemente, von denen genau eines ein <QueryPlan>-Unterelement enthält
Ein <StmtCursor>-Element mit genau einem <CursorPlan>-Unterelement
Ein oder mehrere <StmtSimple>-Elemente ohne <QueryPlan>-Unterelement und ein <StmtCursor>-Element mit einem <CursorPlan>-Unterelement
Sie können den Plan mithilfe von USE PLAN ändern (z. B. die Verknüpfungsreihenfolge und Operatoren ändern sowie Scans und Suchen anpassen), bevor Sie ihn verwenden. Das Format des Planes muss jedoch auch weiterhin Showplanxml.xsd entsprechen. Möglicherweise sind Sie nicht in der Lage, einen Plan zu erzwingen, der geändert wurde. Wenn Sie einen Plan in einem USE PLAN-Hinweis verwenden, tritt ein Fehler auf, wenn es sich bei diesem Plan nicht um einen der Pläne handelt, die SQL Server normalerweise während der Optimierung für die Abfrage berücksichtigen würde.
Mit dem USE PLAN-Abfragehinweis generierte Abfragepläne werden genau wie andere Abfragepläne zwischengespeichert.
Einschränkungen des USE PLAN-Abfragehinweises
Datenbankänderungen, z. B. das Löschen von Indizes, können einen durch USE PLAN angegebenen Abfrageplan ungültig werden lassen. Ein Abfrageplan kann selbst dann veraltet sein, wenn in dem Plan nicht direkt auf ein gelöschtes Objekt verwiesen wird. Auf einen eindeutigen Index wird z. B. in einem Abfrageplan nicht explizit verwiesen, der Index erzwingt jedoch trotzdem eine Eindeutigkeitseinschränkung für die Daten. Ein Abfrageplan, auf den durch USE PLAN verwiesen wird, kann diese Einschränkung verwenden, damit die Verwendung bestimmter Operatoren zum Erzwingen der Eindeutigkeit vermieden wird.
Manchmal kann die Installation eines Service Packs oder einer neuen Version von SQL Server das Erzwingen eines Planes verhindern, der von einer früheren Version erstellt wurde. Daher sollten alle USE PLAN-Hinweise bei jeder Aktualisierung des Servers getestet werden.
Wenn Sie den USE PLAN-Hinweis in einer Abfrage verwenden, werden alle Verknüpfungshinweise und Indexhinweise in der gleichen Abfrage außer Kraft gesetzt.
USE PLAN kann nicht zusammen mit den FORCE ORDER-, EXPAND VIEWS-, GROUP-, UNION- oder JOIN-Abfragehinweisen verwendet werden oder wenn SET FORCEPLAN auf ON festgelegt wurde.
Nur Abfragepläne, die anderenfalls durch die typische Suchstrategie des Abfrageoptimierers gefunden werden, können mithilfe von USE PLAN erzwungen werden. Diese Pläne geben in der Regel an, dass sich ein untergeordnetes Element jeder Verknüpfung auf der Blattebene befindet. Wenn Sie USE PLAN zum Erzwingen anderer Abfragetypen verwenden, wird ein Fehler ausgelöst.
Erzwungene Abfrageplanelemente
Nicht alle Elemente des als XML formatierten Abfrageplans werden mit dem USE PLAN-Hinweis erzwungen. Elemente, die Skalarausdrücke berechnen, werden ignoriert, ebenso wie einige relationale Ausdrücke. Der Abfrageplan wird für die folgenden Arten von Elementen erzwungen:
Baumstruktur des Planes und Reihenfolge der Auswertung.
Ausführungsalgorithmen wie z. B. Verknüpfungstypen, Sortierung und Vereinigungen.
Indexoperationen wie z. B. Scans, Suchen, Schnittmengen und Vereinigungen.
Objekte, auf die explizit verwiesen wird, z. B. andere Tabellen, Indizes und Funktionen.
SQL Server erzwingt insbesondere die Elemente LogicalOp, PhysicalOp und NodeID, die unter dem <RelOp>-Element zu finden sind, sowie alle Unterelemente, die sich auf den <PhysicalOp>-Operator beziehen. Andere Inhalte unter dem <RelOp>-Element werden von USE PLAN nicht berücksichtigt.
Wichtig |
---|
Informationen zu den Kardinalitätsschätzungen, die durch das <EstimateRows>-Element bestimmt werden, werden vom USE PLAN-Abfragehinweis nicht erzwungen. Da der Abfrageoptimierer Kardinalitätsschätzungen zum Ermitteln des Speicherplatzes verwendet, der für das Ausführen einer Abfrage zugewiesen wird, sollten Sie selbst dann genaue Statistiken verwalten, wenn Sie USE PLAN verwenden. Weitere Informationen finden Sie unter Verwenden von Statistiken zum Verbessern der Abfrageleistung. |
Die folgende Tabelle listet die relationalen Operatorwerte auf, die mit dem USE PLAN-Abfragehinweis für die Elemente PhysicalOp und LogicalOp erzwungen werden, sowie alle Unterelemente, die für die einzelnen PhysicalOp-Werte erforderlich sind. Die Tabelle enthält außerdem zusätzliche Informationen, die für die einzelnen Operatoren erforderlich sind, als Pfade im XPath-Stil, die relativ für das Unterelement sind.
PhysicalOp |
LogicalOp |
Unterelement |
Zusätzliche Informationen1 |
---|---|---|---|
Concatenation |
Concatenation Async Concat |
Concat |
Nicht verfügbar |
Constant Scan |
Constant Scan |
ConstantScan |
Nicht verfügbar |
Deleted Scan |
Deleted Scan |
DeletedScan |
Object/@Table |
UDX |
UDX |
Extension |
@UDXName |
Hash Match |
Inner Join Left Outer Join Right Outer Join Full Outer Join Left Semi Join Left Anti Semi Join Right Semi Join Right Anti Semi Join Aggregate Partial Aggregate Flow Distinct Union |
Hash |
Nicht verfügbar |
RID Lookup |
RID Lookup |
IndexScan |
Object/@Database, Object/@Schema, Object/@Table |
Index Scan Clustered Index Scan |
Index Scan Clustered Index Scan |
IndexScan |
Object/@Database, Object/@Schema, Object/@Table Object/@Index |
Index Seek Clustered Index Seek |
Index Seek Clustered Index Seek |
IndexScan |
Object/@Database, Object/@Schema, Object/@Table Object/@Index |
Inserted Scan |
Inserted Scan |
InsertedScan |
Object/@Table |
Log Row Scan |
Log Row Scan |
LogRowScan |
Nicht verfügbar |
Merge Join |
Inner Join Left Outer Join Right Outer Join Full Outer Join Left Semi Join Left Anti Semi Join Right Semi Join Right Anti Semi Join Cross Join Concatenation Union |
Merge |
Nicht verfügbar |
Merge Interval |
Merge Interval |
MergeInterval |
Nicht verfügbar |
Nested Loops |
Inner Join Left Outer Join Right Outer Join Full Outer Join Left Semi Join Left Anti Semi Join Right Semi Join Right Anti Semi Join Cross Join |
NestedLoops |
Nicht verfügbar |
Parallelism |
Gather Streams Repartition Streams Distribute Streams |
Parallelism |
Nicht verfügbar |
Row Count Spool |
Eager Spool Lazy Spool |
RowCountSpool2 |
Nicht verfügbar |
Segment |
Segment |
Segment |
Nicht verfügbar |
Sequence |
Sequence |
Sequence |
Nicht verfügbar |
Sequence Project |
Compute Scalar |
SequenceProject |
Nicht verfügbar |
Sort |
Sort Distinct Sort |
Sort |
Nicht verfügbar |
Table Spool Index Spool |
Eager Spool Lazy Spool |
Spool2 |
@PrimaryNodeId (nur für sekundäre Spoolvorgänge) ../RelOp/@NodeId (nur für RelOps, die primäre Spoolvorgänge darstellen) |
Stream Aggregate |
Aggregate |
StreamAggregate |
Nicht verfügbar |
Switch |
Switch |
Switch |
Nicht verfügbar |
Table Scan |
Table Scan |
TableScan |
Object/@Database, Object/@Schema, Object/@Table |
Table-valued function |
Table-valued function |
TableValuedFunction |
Object/@Database, Object/@Schema, Object/@Table (Name der Tabellenwertfunktion lautet Object/@Table) |
Top |
Top |
Top |
Nicht verfügbar |
Sort |
Sort |
Sort |
Nicht verfügbar |
Top Sort |
TopN Sort |
TopSort |
Nicht verfügbar |
Table Insert |
Insert |
Update |
Object/@Table |
1 Die Anzahl und Reihenfolge dieser Eingaben für jeden relationalen Operator muss wie in der Tabelle gezeigt vorliegen, damit ein Plan mit USE PLAN erzwungen wird.
2 Die Möglichkeit, einen Plan zu erzwingen, ist insofern eingeschränkt, als ein <RowCountSpool>-Unterelement, das in einem Plan enthalten ist, in einem erzwungenen Plan als ein <RowCountSpool>- oder ein <Spool>-Unterelement auftreten kann. Wenn der Plan ein <Spool>-Unterelement enthält, kann dieses in einem erzwungenen Plan als <Spool>- oder als <RowCountSpool>-Unterelement auftreten.
Die Assert-, Bitmap-, ComputeScalar- und PrintDataFlow-Operatoren werden von USE PLAN ignoriert. Der Filter-Operator wird von USE PLAN berücksichtigt, seine genaue Position im Plan kann jedoch nicht erzwungen werden.
Weitere Informationen zu den logischen und physischen Operatoren, die in Abfragen verwendet werden, finden Sie unter Logische und physikalische Operatoren (Referenz).
Cursorunterstützung
Sie können den USE PLAN-Abfragehinweis mit Abfragen verwenden, die statische oder schnelle Vorwärtscursor angeben, die durch Transact-SQL oder eine API-Cursorfunktion angefordert werden. Statische Transact-SQL-Cursor mit einer Vorwärtsoption werden unterstützt. Dynamische, keysetgesteuerte und Vorwärtscursor werden nicht unterstützt.
Weitere Informationen finden Sie unter Verwenden des USE PLAN-Abfragehinweises für Abfragen mit Cursorn.