Abfragehinweise (Transact-SQL)
Abfragehinweise geben an, dass die angezeigten Hinweise in der gesamten Abfrage verwendet werden sollen. Abfragehinweise wirken sich auf alle Operatoren in der Anweisung aus. Falls UNION in der Hauptabfrage vorkommt, kann nur die letzte Abfrage, die eine UNION-Operation enthält, die OPTION-Klausel aufweisen. Abfragehinweise werden als Teil der OPTION-Klausel angegeben. Wenn mindestens ein Abfragehinweis dazu führt, dass der Abfrageoptimierer keinen gültigen Plan generiert, wird der Fehler 8622 ausgelöst.
Vorsicht |
---|
Da der SQL Server-Abfrageoptimierer in der Regel den optimalen Ausführungsplan für eine Abfrage auswählt, wird empfohlen, dass nur erfahrene Entwickler und Datenbankadministratoren Hinweise verwenden, wenn alle anderen Möglichkeiten sich als unbefriedigend erwiesen haben. |
Betrifft:
Syntax
<query_hint > ::=
{ { HASH | ORDER } GROUP
| { CONCAT | HASH | MERGE } UNION
| { LOOP | MERGE | HASH } JOIN
| FAST number_rows
| FORCE ORDER
| MAXDOP number_of_processors
| OPTIMIZE FOR ( @variable_name { UNKNOWN | = literal_constant } [ , ...n ] )
| OPTIMIZE FOR UNKNOWN
| PARAMETERIZATION { SIMPLE | FORCED }
| RECOMPILE
| ROBUST PLAN
| KEEP PLAN
| KEEPFIXED PLAN
| EXPAND VIEWS
| MAXRECURSION number
| USE PLAN N'xml_plan'| TABLE HINT ( exposed_object_name [ , <table_hint> [ [, ]...n ] ] )<table_hint> ::=
[ NOEXPAND ] {
INDEX (index_value [ ,...n ] ) | INDEX = (index_value)
| FASTFIRSTROW
| FORCESEEK
| HOLDLOCK
| NOLOCK
| NOWAIT
| PAGLOCK
| READCOMMITTED
| READCOMMITTEDLOCK
| READPAST
| READUNCOMMITTED
| REPEATABLEREAD
| ROWLOCK
| SERIALIZABLE
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
Argumente
{ HASH | ORDER } GROUP
Gibt an, dass die in der GROUP BY-, DISTINCT- oder der COMPUTE-Klausel der Abfrage beschriebenen Aggregationen Hash- oder Sortiervorgänge verwenden sollen.{ MERGE | HASH | CONCAT } UNION
Gibt an, dass alle UNION-Vorgänge mithilfe von Merge-, Hash- oder Verkettungsvorgängen für die bei UNION vorkommenden Mengen ausgeführt werden. Wenn mehr als ein UNION-Hinweis angegeben wird, wählt der Abfrageoptimierer unter den angegebenen Hinweisen die Strategie mit dem geringsten Aufwand aus.{ LOOP | MERGE | HASH } JOIN
Gibt an, dass alle Verknüpfungsvorgänge per LOOP JOIN, MERGE JOIN oder HASH JOIN in der gesamten Abfrage ausgeführt werden. Wenn mehr als ein Verknüpfungshinweis angegeben wird, wählt der Optimierer unter den zulässigen Hinweisen die Strategie mit dem geringsten Aufwand aus.Wenn in derselben Abfrage auch ein Verknüpfungshinweis in der FROM-Klausel für ein bestimmtes Tabellenpaar angegeben ist, hat dieser Verknüpfungshinweis Vorrang bei der Verknüpfung der beiden Tabellen; die Abfragehinweise müssen jedoch auch berücksichtigt werden. Deshalb kann der Verknüpfungshinweis für das Tabellenpaar nur die Auswahl der zulässigen Verknüpfungsmethoden für den Abfragehinweis einschränken. Weitere Informationen finden Sie unter Verknüpfungshinweise (Transact-SQL).
FAST number_rows
Gibt an, dass die Abfrage für den schnellen Abruf der ersten number_rows. (eine nicht negative ganze Zahl) optimiert wird. Nachdem die ersten number_rows zurückgegeben wurden, wird die Abfrage fortgesetzt und das vollständige Resultset erstellt.FORCE ORDER
Gibt an, dass die von der Abfragesyntax angegebene Verknüpfungsreihenfolge während der Abfrageoptimierung beibehalten wird. Die Verwendung von FORCE ORDER hat keine Auswirkung auf das mögliche Rollentauschverhalten des Abfrageoptimierers. Weitere Informationen finden Sie unter Grundlegendes zu Hashverknüpfungen.Hinweis In einer MERGE-Anweisung wird als Standard-Verknüpfungsreihenfolge zunächst auf die Quelltabelle und dann auf die Zieltabelle zugegriffen, es sei denn, die WHEN SOURCE NOT MATCHED-Klausel wurde angegeben. Wenn Sie FORCE ORDER angeben, wird dieses Standardverhalten beibehalten.
Informationen zur Vorgehensweise des Abfrageoptimierers von SQL Server beim Erzwingen des FORCE ORDER-Hinweises im Fall einer Abfrage mit enthaltener Sicht finden Sie unter Sichtauflösung.
MAXDOP number
Setzt die Konfigurationsoption max degree of parallelism von sp_configure und die Ressourcenkontrolle für die Abfrage außer Kraft, in der diese Option angegeben wird. Der MAXDOP-Abfragehinweis kann den mit sp_configure konfigurierten Wert überschreiten. Wenn MAXDOP den mit der Ressourcenkontrolle konfigurierten Wert überschreitet, verwendet Database Engine (Datenbankmodul) den in ALTER WORKLOAD GROUP (Transact-SQL) beschriebenen MAXDOP-Wert der Ressourcenkontrolle. Alle semantischen Regeln, die mit der Konfigurationsoption max degree of parallelism verwendet werden können, stehen beim Verwenden des MAXDOP-Abfragehinweises zur Verfügung. Weitere Informationen finden Sie unter max degree of parallelism (Option).Vorsicht Wenn MAXDOP auf 0 (null) festgelegt wird, wählt der Server den maximalen Grad an Parallelität aus. Der Server begrenzt DOP intern auf 64.
OPTIMIZE FOR ( @variable\_name { UNKNOWN | = literal_constant } [ , ...n ] )
Weist den Abfrageoptimierer an, beim Kompilieren und Optimieren der Abfrage einen bestimmten Wert für eine lokale Variable zu verwenden. Dieser Wert wird nur während der Abfrageoptimierung verwendet, nicht während der Abfrageausführung.@variable\_name
Der Name einer lokalen Variablen, die in einer Abfrage verwendet wird und der ein Wert für die Verwendung mit dem OPTIMIZE FOR-Abfragehinweis zugewiesen werden kann.UNKNOWN
Gibt an, dass der Abfrageoptimierer statistische Daten statt des Anfangswerts verwenden soll, um während der Abfrageoptimierung den Wert einer lokalen Variablen zu bestimmen.literal_constant
Ein Literalkonstantenwert, dem @variable\_name für die Verwendung mit dem OPTIMIZE FOR-Abfragehinweis zugewiesen werden soll. literal_constant wird nur während der Abfrageoptimierung verwendet, nicht während der Abfrageausführung als Wert von @variable\_name. Für literal_constant ist jeder SQL Server-Systemdatentyp möglich, der als Literalkonstante ausgedrückt werden kann. Der Datentyp von literal_constant muss implizit in den Datentyp konvertierbar sein, auf den @variable\_name in der Abfrage verweist.
OPTIMIZE FOR kann dem Standard-Parametererkennungsverhalten des Abfrageoptimierers entgegenwirken oder kann beim Erstellen von Planhinweislisten verwendet werden. Weitere Informationen finden Sie unter Erneutes Kompilieren gespeicherter Prozeduren und Optimieren von Abfragen in bereitgestellten Anwendungen mit Planhinweislisten.
OPTIMIZE FOR UNKNOWN
Weist den Abfrageoptimierer an, beim Kompilieren und Optimieren der Abfrage für alle lokalen Variablen, einschließlich der Parameter, die mit erzwungener Parametrisierung erstellt werden, statistische Daten statt der Anfangswerte zu verwenden. Weitere Informationen zu erzwungener Parametrisierung finden Sie unter Erzwungene Parametrisierung.Werden OPTIMIZE FOR @variable\_name = literal_constant und OPTIMIZE FOR UNKNOWN im selben Abfragehinweis verwendet, verwendet der Abfrageoptimierer die literal_constant, die für einen bestimmten Wert angegeben wurde, und UNKNOWN für die übrigen Variablenwerte. Diese Werte werden nur während der Abfrageoptimierung verwendet und nicht während der Abfrageausführung.
PARAMETERIZATION { SIMPLE | FORCED }
Gibt die Parametrisierungsregeln an, die der SQL Server-Abfrageoptimierer bei der Kompilierung auf die Abfrage anwendet.Wichtig Der PARAMETERIZATION-Abfragehinweis kann nur innerhalb einer Planhinweisliste angegeben werden. Er kann nicht direkt innerhalb einer Abfrage angegeben werden.
Mit SIMPLE wird der Abfrageoptimierer angewiesen, einfache Parametrisierung auszuführen. Mit FORCED wird der Optimierer angewiesen, die erzwungene Parametrisierung auszuführen. Mit dem PARAMETERIZATION-Abfragehinweis wird die aktuelle Einstellung der Option PARAMETERIZATION database SET innerhalb einer Planhinweisliste außer Kraft gesetzt. Weitere Informationen finden Sie unter Angeben des Abfrageparametrisierungsverhaltens mithilfe von Planhinweislisten.
RECOMPILE
Weist SQL Server Database Engine (Datenbankmodul) an, den für die Abfrage generierten Abfrageplan nach der Ausführung zu verwerfen. Dadurch wird der Abfrageoptimierer gezwungen, erneut einen Abfrageplan zu kompilieren, wenn dieselbe Abfrage das nächste Mal ausgeführt wird. Wenn RECOMPILE nicht angegeben wird, werden Abfragepläne von Database Engine (Datenbankmodul) zwischengespeichert und wiederverwendet. Beim Kompilieren von Abfrageplänen verwendet der RECOMPILE-Abfragehinweis die aktuellen Werte von lokalen Variablen in der Abfrage und, falls sich die Abfrage innerhalb einer gespeicherten Prozedur befindet, die an Parameter übergebenen aktuellen Werte.RECOMPILE ist eine hilfreiche Alternative zum Erstellen einer gespeicherten Prozedur, die die WITH RECOMPILE-Klausel verwendet, wenn nicht die gesamte gespeicherte Prozedur, sondern nur eine Teilmenge davon erneut kompiliert werden muss. Weitere Informationen finden Sie unter Erneutes Kompilieren gespeicherter Prozeduren. RECOMPILE ist auch beim Erstellen von Planhinweislisten hilfreich. Weitere Informationen finden Sie unter Optimieren von Abfragen in bereitgestellten Anwendungen mit Planhinweislisten.
ROBUST PLAN
Zwingt den Abfrageoptimierer zu einer Vorgehensweise, bei der der Schwerpunkt auf der maximalen potenziellen Zeilengröße liegt. Dies geht möglicherweise zu Lasten der Leistung. Bei der Verarbeitung der Abfrage müssen möglicherweise Zwischentabellen und Operatoren Zeilen speichern und verarbeiten, die größer sind als alle Eingabezeilen. Die Zeilen können so groß sein, dass der jeweilige Operator in einigen Fällen die Zeile nicht verarbeiten kann. In diesem Fall gibt Database Engine (Datenbankmodul) während der Ausführung der Abfrage einen Fehler aus. Durch das Verwenden von ROBUST PLAN weisen Sie den Abfrageoptimierer an, keine Abfragepläne in Betracht zu ziehen, für die möglicherweise dieses Problem auftritt.Ist eine solche Vorgehensweise nicht möglich, gibt der Abfrageoptimierer einen Fehler zurück, statt die Fehlererkennung auf die Abfrageausführung zu verschieben. Die Zeilen können Spalten variabler Länge aufweisen. Database Engine (Datenbankmodul) lässt die Definition von Zeilen zu, deren maximale potenzielle Größe von Database Engine (Datenbankmodul) nicht mehr verarbeitet werden kann. Trotz der maximalen potenziellen Größe speichert eine Anwendung im Allgemeinen Zeilen, deren tatsächliche Größe innerhalb der Höchstwerte liegen, die Database Engine (Datenbankmodul) verarbeiten kann. Wenn Database Engine (Datenbankmodul) eine Zeile ermittelt, die zu lang ist, wird ein Ausführungsfehler zurückgegeben.
KEEP PLAN
Zwingt den Abfrageoptimierer, den geschätzten Neukompilierungsschwellenwert für eine Abfrage zu lockern. Der geschätzte Neukompilierungsschwellenwert gibt den Punkt an, bei dem eine Abfrage automatisch erneut kompiliert wird, wenn für eine Tabelle die geschätzte Anzahl von Änderungen für indizierte Spalten durch Ausführen der Anweisungen UPDATE, DELETE, MERGE oder INSERT vorgenommen wurden. Durch Angeben von KEEP PLAN wird sichergestellt, dass eine Abfrage nicht zu häufig erneut kompiliert wird, wenn an einer Tabelle mehrere Aktualisierungen ausgeführt werden.KEEPFIXED PLAN
Zwingt den Abfrageoptimierer, die Abfrage aufgrund von Änderungen in den Statistiken nicht erneut zu kompilieren. Durch Angeben von KEEPFIXED PLAN wird sichergestellt, dass eine Abfrage nur dann erneut kompiliert wird, wenn das Schema der zugrunde liegenden Tabellen geändert wird oder für diese Tabellen sp_recompile ausgeführt wird.EXPAND VIEWS
Gibt an, dass die indizierten Sichten erweitert werden und dass der Abfrageoptimierer eine indizierte Sicht nicht als Ersatz für einen beliebigen Teil der Abfrage auffasst. Eine Sicht wird erweitert, indem der Sichtname im Abfragetext durch die Sichtdefinition ersetzt wird.Dieser Abfragehinweis lässt die direkte Verwendung von indizierten Sichten und Indizes für indizierte Sichten im Abfrageplan praktisch nicht zu.
Die indizierte Sicht wird nur dann nicht erweitert, wenn auf die Sicht im SELECT-Teil der Abfrage direkt verwiesen wird und WITH (NOEXPAND) oder WITH (NOEXPAND, INDEX( index_value [ ,...n ] ) ) angegeben ist. Weitere Informationen zum Abfragehinweis WITH (NOEXPAND) finden Sie unter FROM.
Der Hinweis wirkt sich nur auf die Sichten im SELECT-Teil von Anweisungen aus, einschließlich der Sichten in den Anweisungen INSERT, UPDATE, MERGE und DELETE.
MAXRECURSION number
Gibt die maximale Anzahl zugelassener Rekursionen für diese Abfrage an. number ist eine nicht negative ganze Zahl zwischen 0 und 32767. Wenn 0 angegeben wird, wird keine Beschränkung angewendet. Wenn diese Option nicht angegeben wird, beträgt das Standardlimit für den Server 100.Wenn der angegebene Wert bzw. der Standardwert für MAXRECURSION während der Ausführung der Abfrage erreicht wird, wird die Abfrage beendet und ein Fehler wird zurückgegeben.
Aufgrund dieses Fehlers wird für alle Änderungen aufgrund der Anweisung ein Rollback ausgeführt. Falls es sich hierbei um eine SELECT-Anweisung handelt, können Teilergebnisse oder keine Ergebnisse zurückgegeben werden. Teilergebnisse schließen möglicherweise nicht alle Zeilen auf Rekursionsebenen ein, die über die angegebene maximale Rekursionsebene hinausgehen.
Weitere Informationen finden Sie unter WITH common_table_expression (Transact-SQL).
USE PLAN N**'xml_plan'**
Zwingt den Abfrageoptimierer, für eine Abfrage einen vorhandenen Abfrageplan zu verwenden, der mit 'xml_plan' angegeben ist. Weitere Informationen finden Sie unter Angeben von Abfrageplänen mit Planerzwingung. USE PLAN kann nicht für die Anweisungen INSERT, UPDATE, MERGE oder DELETE angegeben werden.TABLE HINT (exposed_object_name [ , <table_hint> [ [, ]...n ] ] )
Wendet den angegebenen Tabellenhinweis auf die Tabelle oder die Sicht an, die exposed_object_name entspricht. Es wird empfohlen, einen Tabellenhinweis nur im Kontext einer Planhinweisliste als einen Abfragehinweis zu verwenden.exposed_object_name kann einer der folgenden Verweise sein:
Wenn ein Alias für die Tabelle oder die Sicht in der FROM-Klausel der Abfrage verwendet wird, ist exposed_object_name der Alias.
Wenn kein Alias verwendet wird, entspricht exposed_object_name genau der Tabelle oder der Sicht, auf die in der FROM-Klausel verwiesen wird. Wenn z. B. mit einem zweiteiligen Namen auf die Tabelle oder die Sicht verwiesen wird, ist exposed_object_name der gleiche zweiteilige Name.
Wenn exposed_object_name angegeben wird, ohne dass auch ein Tabellenhinweis angegeben wird, werden alle in der Abfrage als Teil eines Tabellenhinweises für das Objekt festgelegten Indizes ignoriert, und die Indexverwendung wird vom Abfrageoptimierer bestimmt. Sie können diese Vorgehensweise verwenden, um die Auswirkung eines INDEX-Tabellenhinweises zu eliminieren, wenn Sie die ursprüngliche Abfrage nicht ändern können. Siehe Beispiel J.
<table_hint> ::= { [ NOEXPAND ] { INDEX ( index_value [ ,...n ] ) | INDEX = ( index_value ) | FASTFIRSTROW | FORCESEEK | HOLDLOCK | NOLOCK | NOWAIT | PAGLOCK | READCOMMITTED | READCOMMITTEDLOCK | READPAST | READUNCOMMITTED | REPEATABLEREAD | ROWLOCK | SERIALIZABLE | TABLOCK | TABLOCKX | UPDLOCK | XLOCK }
Der Tabellenhinweis, der auf die Tabelle oder die Sicht anzuwenden ist, die exposed_object_name als Abfragehinweis entspricht. Eine Beschreibung dieser Hinweise finden Sie unter Tabellenhinweise (Transact-SQL).Andere Tabellenhinweise als INDEX und FORCESEEK sind als Abfragehinweise nicht zulässig, es sei denn, die Abfrage enthält bereits eine WITH-Klausel, die einen Tabellenhinweis angibt. Weitere Informationen finden Sie im Abschnitt zu den Hinweisen.
Hinweise
Abfragehinweise können nicht in einer INSERT-Anweisung angegeben werden, es sei denn, eine SELECT-Klausel wird innerhalb der Anweisung verwendet.
Abfragehinweise können nicht in Unterabfragen, sondern nur in der Abfrage der obersten Ebene angegeben werden. Wenn ein Tabellenhinweis als Abfragehinweis angegeben ist, kann der Hinweis in der Abfrage der obersten Ebene oder in einer Unterabfrage angegeben werden. Der für exposed_object_name in der TABLE HINT-Klausel angegebene Wert muss jedoch genau dem verfügbar gemachten Namen in der Abfrage oder Unterabfrage entsprechen.
Angeben von Tabellenhinweisen als Abfragehinweise
Es wird empfohlen, den INDEX- oder den FORCESEEK-Tabellenhinweis nur im Zusammenhang mit einer Planhinweisliste als Abfragehinweis zu verwenden. Planhinweislisten sind nützlich, wenn Sie die ursprüngliche Abfrage nicht ändern können, beispielsweise bei Anwendungen von Drittanbietern. Der in der Planhinweisliste angegebene Abfragehinweis wird vor dem Kompilieren und Optimieren zur Abfrage hinzugefügt. Verwenden Sie für Ad-hoc-Abfragen die TABLE HINT-Klausel nur dann, wenn Sie Planhinweislisten-Anweisungen testen. Es wird empfohlen, für alle anderen Ad-hoc-Abfragen diese Hinweise nur als Tabellenhinweise anzugeben.
Wenn die INDEX-Tabellenhinweise und die FORCESEEK-Tabellenhinweise als Abfragehinweise angegeben werden, sind sie für die folgenden Objekte gültig:
Tabellen
Sichten
Indizierte Sichten
Allgemeine Tabellenausdrücke (Der Hinweis muss in der SELECT-Anweisung angegeben sein, mit deren Resultset der allgemeine Tabellenausdruck aufgefüllt wird.)
Dynamische Verwaltungssichten
Benannte Unterabfragen
Der INDEX- und der FORCESEEK-Tabellenhinweis können als Abfragehinweise für eine Abfrage angegeben werden, die nicht über vorhandene Tabellenhinweise verfügt, oder sie können verwendet werden, um vorhandene INDEX- oder FORCESEEK-Hinweise in der Abfrage zu ersetzen. Andere Tabellenhinweise als INDEX und FORCESEEK sind als Abfragehinweise nicht zulässig, es sei denn, die Abfrage enthält bereits eine WITH-Klausel, die einen Tabellenhinweis angibt. In diesem Fall muss, um die Semantik der Abfrage beizubehalten, mithilfe von TABLE HINT in der OPTION-Klausel auch ein übereinstimmender Hinweis als Abfragehinweis angegeben werden. Wenn die Abfrage beispielsweise den Tabellenhinweis NOLOCK enthält, muss die OPTION-Klausel im @hints-Parameter der Planhinweisliste ebenfalls den NOLOCK-Hinweis enthalten. Siehe Beispiel K. Wenn ein anderer Tabellenhinweis als INDEX oder FORCESEEK mithilfe von TABLE HINT in der OPTION-Klausel ohne übereinstimmenden Abfragehinweis angegeben wurde (oder umgekehrt), wird der Fehler 8702 ausgelöst (als Hinweis darauf, dass die OPTION-Klausel bewirken kann, dass sich die Semantik der Abfrage ändert), und die Abfrage schlägt fehl. Weitere Informationen finden Sie unter Verwenden der INDEX- und FORCESEEK-Abfragehinweise in Planhinweislisten.
Beispiele
A. Verwenden von MERGE JOIN
Im folgenden Beispiel wird der JOIN-Vorgang in der Abfrage durch MERGE JOIN ausgeführt.
USE AdventureWorks;
GO
SELECT *
FROM Sales.Customer AS c
INNER JOIN Sales.CustomerAddress AS ca ON c.CustomerID = ca.CustomerID
WHERE TerritoryID = 5
OPTION (MERGE JOIN);
GO
B. Verwenden von OPTIMIZE FOR
Im folgenden Beispiel wird der Abfrageoptimierer angewiesen, den Wert 'Seattle' für die lokale Variable @city\_name zu verwenden, und statistische Daten zu verwenden, um während der Abfrageoptimierung den Wert der lokalen Variablen @postal\_code zu bestimmen.
USE AdventureWorks;
GO
DECLARE @city_name nvarchar(30);
DECLARE @postal_code nvarchar(15);
SET @city_name = 'Ascheim';
SET @postal_code = 86171;
SELECT * FROM Person.Address
WHERE City = @city_name AND PostalCode = @postal_code
OPTION ( OPTIMIZE FOR (@city_name = 'Seattle', @postal_code UNKNOWN) );
GO
C. Verwenden von MAXRECURSION
MAXRECURSION kann verwendet werden, um zu verhindern, dass ein fehlerhaft formatierter allgemeiner Tabellenausdruck in eine Endlosschleife gerät. Im folgenden Beispiel wird absichtlich eine Endlosschleife erstellt. Außerdem wird die Anzahl der Rekursionsebenen mithilfe von MAXRECURSION auf zwei beschränkt.
USE AdventureWorks;
GO
--Creates an infinite loop
WITH cte (EmployeeID, ManagerID, Title) AS
(
SELECT EmployeeID, ManagerID, Title
FROM HumanResources.Employee
WHERE ManagerID IS NOT NULL
UNION ALL
SELECT cte.EmployeeID, cte.ManagerID, cte.Title
FROM cte
JOIN HumanResources.Employee AS e
ON cte.ManagerID = e.EmployeeID
)
--Uses MAXRECURSION to limit the recursive levels to 2
SELECT EmployeeID, ManagerID, Title
FROM cte
OPTION (MAXRECURSION 2);
GO
Nach dem Beheben des Codierungsfehlers ist MAXRECURSION nicht mehr erforderlich.
D. Verwenden von MERGE UNION
Im folgenden Beispiel wird der MERGE UNION-Abfragehinweis verwendet.
USE AdventureWorks;
GO
SELECT *
FROM HumanResources.Employee AS e1
UNION
SELECT *
FROM HumanResources.Employee AS e2
OPTION (MERGE UNION);
GO
E. Verwenden von HASH GROUP und FAST
Im folgenden Beispiel werden die Abfragehinweise HASH GROUP und FAST verwendet.
USE AdventureWorks;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (HASH GROUP, FAST 10);
GO
F. Verwenden von MAXDOP
Im folgenden Beispiel wird der MAXDOP-Abfragehinweis verwendet.
USE AdventureWorks ;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (MAXDOP 2);
GO
G. Verwenden von INDEX
In den folgenden Beispielen wird der INDEX-Hinweis verwendet. Im ersten Beispiel wird ein einzelner Index angegeben. Im zweiten Beispiel werden mehrere Indizes für einen einzelnen Tabellenverweis angegeben. Da der INDEX-Hinweis auf eine Tabelle angewendet wird, die einen Alias verwendet, muss in beiden Beispielen auch in der TABLE HINT-Klausel der gleiche Alias wie der verfügbar gemachte Objektname angegeben werden.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide1',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e, INDEX (IX_Employee_ManagerID)))';
GO
EXEC sp_create_plan_guide
@name = N'Guide2',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e, INDEX(PK_Employee_EmployeeID, IX_Employee_ManagerID)))';
GO
H. Verwenden von FORCESEEK
Im folgenden Beispiel wird der FORCESEEK-Tabellenhinweis verwendet. Da der INDEX-Hinweis auf eine Tabelle angewendet wird, die einen zweiteiligen Namen verwendet, muss auch in der TABLE HINT-Klausel der gleiche zweiteilige Name wie der verfügbar gemachte Objektname angegeben werden.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide3',
@stmt = N'SELECT c.LastName, c.FirstName, HumanResources.Employee.Title
FROM HumanResources.Employee
JOIN Person.Contact AS c ON HumanResources.Employee.ContactID = c.ContactID
WHERE HumanResources.Employee.ManagerID = 3
ORDER BY c.LastName, c.FirstName;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT( HumanResources.Employee, FORCESEEK))';
GO
I. Verwenden von mehreren Tabellenhinweisen
Im folgenden Beispiel wird der INDEX-Hinweis auf eine Tabelle angewendet, und der FORCESEEK-Hinweis wird auf eine andere Tabelle angewendet.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide4',
@stmt = N'SELECT e.ManagerID, c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_ManagerID ) )
, TABLE HINT ( c, FORCESEEK) )';
GO
J. Verwenden von TABLE HINT zum Überschreiben eines vorhandenen Tabellenhinweises
Im folgenden Beispiel wird dargestellt, wie der TABLE HINT-Hinweis verwendet wird, ohne einen Hinweis zum Überschreiben des Verhaltens des in der FROM-Klausel der Abfrage angegebenen INDEX-Tabellenhinweises anzugeben.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide5',
@stmt = N'SELECT e.ManagerID, c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e WITH (INDEX (IX_Employee_ManagerID))
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e))';
GO
K. Angeben von Tabellenhinweisen, die die Semantik beeinflussen
Das folgende Beispiel enthält in der Abfrage zwei Tabellenhinweise: den NOLOCK-Hinweis, der die Semantik beeinflusst, und den INDEX-Hinweis, der die Semantik nicht beeinflusst. Der NOLOCK-Hinweis wird in der OPTIONS-Klausel der Planhinweisliste angegeben, um die Semantik der Abfrage beizubehalten. Neben dem NOLOCK-Hinweis werden auch der INDEX-Hinweis und der FORCESEEK-Hinweis angegeben, die den die Semantik nicht beeinflussenden INDEX-Hinweis in der Abfrage ersetzen, wenn die Anweisung kompiliert und optimiert wird.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide6',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
WITH (NOLOCK, INDEX (PK_Employee_EmployeeID))
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_ManagerID) , NOLOCK, FORCESEEK ))';
GO
Im folgenden Beispiel wird eine alternative Methode dargestellt, um die Semantik der Abfrage beizubehalten und zu ermöglichen, dass der Abfrageoptimierer einen anderen als den im Tabellenhinweis angegebenen Index verwendet. Dies erfolgt durch Angabe des NOLOCK-Hinweises in der OPTIONS-Klausel (da dieser die Semantik beeinflusst) und durch Angabe des TABLE HINT-Schlüsselworts nur mit einem Tabellenverweis und ohne INDEX-Hinweis.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide7',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
WITH (NOLOCK, INDEX (PK_Employee_EmployeeID))
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, NOLOCK))';
GO