Teilen über


sp_create_plan_guide (Transact-SQL)

Gilt für: SQL Server Azure SQL-Datenbank Azure SQL Managed Instance

Erstellt eine Planhinweisliste für die Zuordnung von Abfragehinweisen oder tatsächlichen Abfrageplänen zu Abfragen in einer Datenbank. Weitere Informationen zu Planhinweislisten finden Sie unter Planhinweislisten.

Transact-SQL-Syntaxkonventionen

Syntax

sp_create_plan_guide
    [ @name = ] N'name'
    [ , [ @stmt = ] N'stmt' ]
    , [ @type = ] { N'OBJECT' | N'SQL' | N'TEMPLATE' }
    [ , [ @module_or_batch = ] { N' [ schema_name. ] object_name' | N'batch_text' } ]
    [ , [ @params = ] N'@parameter_name data_type [ ,... n ]' ]
    [ , [ @hints = ] { N'OPTION ( query_hint [ , ...n ] )' | N'XML_showplan' } ]
[ ; ]

Argumente

[ @name = ] N'name'

Der Name des Planleitfadens. @name ist "sysname" ohne Standard und eine maximale Länge von 124 Zeichen. Die Gültigkeit der Namen von Planhinweislisten beschränkt sich auf die aktuelle Datenbank. @name müssen die Regeln für Bezeichner einhalten und dürfen nicht mit dem Nummernzeichen (#) beginnen.

[ @stmt = ] N'stmt'

Eine Transact-SQL-Anweisung zum Erstellen eines Planleitfadens. @stmt ist nvarchar(max), mit einem Standardwert von NULL. Wenn der SQL Server-Abfrageoptimierer eine Abfrage erkennt, die @stmt entspricht, wird @name wirksam. Damit die Erstellung eines Planleitfadens erfolgreich ist, muss @stmt im durch die parameter @type, @module_or_batch und @params angegebenen Kontext angezeigt werden.

@stmt müssen so bereitgestellt werden, dass der Abfrageoptimierer sie mit der entsprechenden Anweisung abgleichen kann, die innerhalb des durch @module_or_batch und @params identifizierten Batch- oder Moduls angegeben wird. Weitere Informationen finden Sie im Abschnitt Hinweise. Die Größe der @stmt ist nur durch den verfügbaren Arbeitsspeicher des Servers begrenzt.

[ @type = ] { N'OBJECT' | N'SQL' | N'TEMPLATE' }

Der Typ der Entität, in der @stmt angezeigt wird. Dadurch wird der Kontext für den Abgleich @stmt zum @name angegeben. @type ist nvarchar(60), und kann einer der folgenden Werte sein:

  • OBJECT

    Gibt an , @stmt im Kontext einer gespeicherten Transact-SQL-Prozedur, skalaren Funktion, mehrwertigen Funktion oder Transact-SQL-DML-Trigger in der aktuellen Datenbank angezeigt wird.

  • SQL

    Gibt an , @stmt im Kontext einer eigenständigen Anweisung oder eines Batches angezeigt wird, der über einen beliebigen Mechanismus an SQL Server übermittelt werden kann. Transact-SQL-Anweisungen, die von ClR-Objekten (Common Language Runtime) oder erweiterten gespeicherten Prozeduren oder mit Verwendung EXEC N'<sql_string>'übermittelt werden, werden als Batches auf dem Server verarbeitet und sollten daher als @type von SQLidentifiziert werden. Wenn SQL angegeben, kann der Abfragehinweis PARAMETERIZATION { FORCED | SIMPLE } nicht im @hints-Parameter angegeben werden.

  • TEMPLATE

    Gibt an, dass die Plananleitung auf jede Abfrage angewendet wird, die auf das formular parametrisiert wird, das in @stmt angegeben ist. Wenn TEMPLATE angegeben, kann nur der PARAMETERIZATION { FORCED | SIMPLE } Abfragehinweis im @hints-Parameter angegeben werden. Weitere Informationen zu TEMPLATE Planhandbüchern finden Sie unter Angeben des Abfrageparameterverhaltens mithilfe von Planhandbüchern.

[ @module_or_batch = ] { N' [ schema_name. ] object_name' | N'batch_text' }

Gibt entweder den Namen des Objekts an, in dem @stmt angezeigt wird, oder den Batchtext, in dem @stmt angezeigt wird. @module_or_batch ist nvarchar(max), mit einem Standardwert von NULL. Der Batchtext kann keine Anweisung enthalten USE <database> .

Damit ein Planleitfaden mit einem von einer Anwendung übermittelten Batch übereinstimmt, muss @module_or_batch im gleichen Format wie zeichenweise bereitgestellt werden, wie er an SQL Server übermittelt wird. Es findet keine interne Konvertierung zur Vereinfachung dieses Abgleichs statt. Weitere Informationen finden Sie im Abschnitt Hinweise.

[ <schema_name>. ] <object_name>Gibt den Namen einer gespeicherten Transact-SQL-Prozedur, Skalarfunktion, Mehrwertfunktion oder Transact-SQL-DML-Trigger an, der @stmt enthält. Wenn <schema_name> nicht angegeben, <schema_name> wird das Schema des aktuellen Benutzers verwendet. Wenn NULL angegeben und @type ist SQL, wird der Wert von @module_or_batch auf den Wert von @stmt festgelegt. Wenn @type ist TEMPLATE, muss @module_or_batch sein NULL.

[ @params = ] N'@parameter_name data_type [ ,... n ]'

Gibt die Definitionen aller Parameter an, die in @stmt eingebettet sind. @params ist nvarchar(max), mit einem Standardwert von NULL. @params gilt nur, wenn eine der folgenden Optionen zutrifft:

  • @type ist SQL oder TEMPLATE. Wenn TEMPLATE, @params darf nicht sein NULL.

  • @stmt wird mithilfe und sp_executesql ein Wert für den parameter @params angegeben, oder SQL Server sendet intern eine Anweisung nach der Parameterisierung. Die Übermittlung parametrisierter Abfragen von Datenbank-APIs (einschließlich ODBC, OLE DB und ADO.NET) wird SQL Server als Aufrufe sp_executesql oder an API-Servercursorroutinen angezeigt. Daher können sie auch von SQL Oder TEMPLATE Planhandbüchern abgeglichen werden.

@params muss im genauen Format angegeben werden, das an SQL Server übermittelt wird, entweder mithilfe sp_executesql oder intern nach der Parametrierung. Weitere Informationen finden Sie im Abschnitt Hinweise. Wenn der Batch keine Parameter enthält, NULL muss angegeben werden. Die Größe der @params ist nur durch den verfügbaren Serverspeicher begrenzt.

[ @hints = ] { N'OPTION ( query_hint [ , ... n ] )' | N'XML_showplan' }

@hints ist nvarchar(max), mit einem Standardwert von NULL.

  • OPTION ( <query_hint> [ , ...n ] )

    Gibt eine OPTION Klausel an, die an eine Abfrage angefügt werden soll, die @stmt entspricht. @hints müssen syntaktisch identisch mit einer Klausel in einer OPTION SELECT Anweisung sein und können eine beliebige gültige Abfolge von Abfragehinweisen enthalten.

  • <XML_showplan>'

    Der Abfrageplan im XML-Format, der als Hinweis angewendet werden soll.

    Es wird empfohlen, den XML-Showplan einer Variablen zuzuweisen. Andernfalls müssen Sie alle einfachen Anführungszeichen im Showplan escapen, indem Sie ihnen ein weiteres einfaches Anführungszeichen voranstellen. Siehe Beispiel E.

  • NULL

    Gibt an, dass alle in der OPTION Klausel der Abfrage angegebenen Hinweise nicht auf die Abfrage angewendet werden. Weitere Informationen finden Sie unter OPTION-Klausel.

Hinweise

Die Argumente, die sp_create_plan_guide in der angezeigten Reihenfolge angegeben werden müssen. Wenn Sie Werte für die Parameter von sp_create_plan_guide angeben, müssen entweder alle oder überhaupt keine Parameternamen explizit angegeben werden. Wird z. B. @name = angegeben, müssen auch @stmt = , @type = usw. angegeben werden. Ebenso dürfen, wenn @name = nicht angegeben und nur der Parameterwert bereitgestellt wird, die übrigen Parameterwerte ebenfalls nicht angegeben und nur ihre Werte bereitgestellt werden. Argumentnamen dienen nur zu Beschreibungszwecken, zum besseren Verständnis der Syntax. SQL Server überprüft nicht, ob der angegebene Parametername dem Namen für den Parameter an der Position entspricht, an der der Name verwendet wird.

Sie können mehr als eine oder SQL mehrere OBJECT Planleitfaden für die gleiche Abfrage und denselben Batch oder dasselbe Modul erstellen. Es kann jedoch nur jeweils eine Planhinweisliste aktiviert sein.

Planführungslinien vom Typ OBJECT können nicht für einen @module_or_batch Wert erstellt werden, der auf eine gespeicherte Prozedur, Funktion oder einen DML-Trigger verweist, der die WITH ENCRYPTION Klausel angibt oder temporär ist.

Das Löschen oder Ändern einer Funktion, einer gespeicherten Prozedur oder eines DML-Triggers, auf die bzw. den in einer Planhinweisliste verwiesen wird, verursacht einen Fehler. Wenn Sie versuchen, eine Tabelle abzulegen, die als Auslöser definiert ist, auf den ein Planleitfaden verweist, tritt auch ein Fehler auf.

Planhandbücher können nicht in jeder Edition von SQL Server verwendet werden. Eine Liste der Funktionen, die von den SQL Server-Editionen unterstützt werden, finden Sie unter Editionen und unterstützte Funktionen von SQL Server 2022. Planhinweislisten sind in jeder Edition sichtbar. Sie können auch in allen Versionen eine Datenbank anfügen, die Planhinweislisten enthält. Planhinweislisten bleiben beim Wiederherstellen oder Anfügen einer Datenbank in einer aktualisierten Version von SQL Server erhalten. Nach dem Serverupgrade sollten Sie in jeder Datenbank prüfen, ob die Planhinweislisten wirklich erwünscht sind.

Planleitfaden übereinstimmende Anforderungen

Für Planhandbücher, die @type einer Abfrage angeben oder TEMPLATE erfolgreich abgleichen möchten, werden die Werte für @module_or_batch und @params [SQL, ... n ] muss im gleichen Format wie die von der Anwendung eingereichten Gegenstücken bereitgestellt werden. Dies bedeutet, dass Sie den Batchtext genau so bereitstellen müssen, wie der SQL Server-Compiler ihn empfängt. Um den tatsächlichen Batch- und Parametertext zu erfassen, können Sie SQL Server Profiler verwenden. Weitere Informationen finden Sie unter Verwenden von SQL Server Profiler zum Erstellen und Testen von Planhandbüchern.

Wenn @type ist und @module_or_batch festgelegt ist, wird der Wert @module_or_batch auf den Wert von @stmt festgelegtNULL. SQL Dies bedeutet, dass der Wert für @stmt genau das gleiche Format, Zeichen für Zeichen, wie er an SQL Server übermittelt wird, bereitgestellt werden muss. Es findet keine interne Konvertierung zur Vereinfachung dieses Abgleichs statt.

Wenn SQL Server mit dem Wert von @stmt @module_or_batch und @params [, ... n ], oder wenn @type istOBJECT, werden die folgenden Zeichenfolgenelemente nicht berücksichtigt, um den Text der entsprechenden Abfrage innerhalb <object_name>der abfrage zu senden:

  • Leerzeichen (Tabstopps, Leerzeichen, Wagenrücklauf oder Zeilenfeeds) innerhalb der Zeichenfolge
  • Kommentare (-- oder /* */)
  • Nachfolgende Semikolons

Beispielsweise kann SQL Server mit der @stmt Zeichenfolge N'SELECT * FROM T WHERE a = 10' mit dem folgenden @module_or_batch übereinstimmen:

 N'SELECT *
 FROM T
 WHERE a = 10'

Die gleiche Zeichenfolge würde jedoch nicht mit diesem @module_or_batch übereinstimmen:

N'SELECT * FROM T WHERE b = 10'

SQL Server ignoriert die Wagenrücklauf-, Zeilenvorschub- und Leerzeichen innerhalb der ersten Abfrage. In der zweiten Abfrage wird die Sequenz WHERE b = 10 nicht auf die gleiche Art interpretiert wie WHERE a = 10. Bei übereinstimmungen wird zwischen Groß- und Kleinschreibung unterschieden (auch wenn bei der Sortierung der Datenbank die Groß-/Kleinschreibung nicht beachtet wird), es sei denn, es gibt Schlüsselwörter, bei denen die Groß-/Kleinschreibung nicht beachtet wird. Der Abgleich ist für Leerzeichen vertraulich. Bei der Feststellung der Übereinstimmung wird nicht nach verkürzten Formen von Schlüsselwörtern unterschieden. So werden beispielsweise die Schlüsselwörter EXECUTE, EXEC und execute als gleichwertig angesehen.

Planleitfadeneffekt auf den Plancache

Wenn Sie eine Planhinweisliste für ein Modul erstellen, wird der Abfrageplan für dieses Modul aus dem Plancache entfernt. Beim Erstellen eines Planleitfadens vom Typ OBJECT oder SQL in einem Batch wird der Abfrageplan für einen Batch entfernt, der denselben Hashwert aufweist. Beim Erstellen eines Planleitfadens vom Typ TEMPLATE werden alle Batches mit einer einzelnen Anweisung aus dem Plancache in dieser Datenbank entfernt.

Berechtigungen

Zum Erstellen eines Planleitfadens des Typs OBJECTist die Berechtigung für das referenzierte Objekt erforderlich ALTER . Zum Erstellen eines Planleitfadens vom Typ SQL oder TEMPLATEist die Berechtigung für die aktuelle Datenbank erforderlich ALTER .

Beispiele

A. Erstellen eines Planleitfadens vom Typ OBJECT für eine Abfrage in einer gespeicherten Prozedur

Im folgenden Beispiel wird eine Planhinweisliste erstellt, die einer im Kontext einer anwendungsbasierten gespeicherten Prozedur ausgeführten Abfrage zugeordnet wird, und der OPTIMIZE FOR-Hinweis auf die Abfrage angewendet.

Hier ist die gespeicherte Prozedur:

IF OBJECT_ID(N'Sales.GetSalesOrderByCountry', N'P') IS NOT NULL
    DROP PROCEDURE Sales.GetSalesOrderByCountry;
GO

CREATE PROCEDURE Sales.GetSalesOrderByCountry (
    @Country_region NVARCHAR(60)
)
AS
BEGIN
    SELECT *
    FROM Sales.SalesOrderHeader AS h
    INNER JOIN Sales.Customer AS c
        ON h.CustomerID = c.CustomerID
    INNER JOIN Sales.SalesTerritory AS t
        ON c.TerritoryID = t.TerritoryID
    WHERE t.CountryRegionCode = @Country_region;
END
GO

Hier sehen Sie die Plananleitung, die in der Abfrage in der gespeicherten Prozedur erstellt wurde:

EXEC sp_create_plan_guide
    @name = N'Guide1',
    @stmt = N'SELECT *
              FROM Sales.SalesOrderHeader AS h
              INNER JOIN Sales.Customer AS c
                 ON h.CustomerID = c.CustomerID
              INNER JOIN Sales.SalesTerritory AS t
                 ON c.TerritoryID = t.TerritoryID
              WHERE t.CountryRegionCode = @Country_region',
    @type = N'OBJECT',
    @module_or_batch = N'Sales.GetSalesOrderByCountry',
    @params = NULL,
    @hints = N'OPTION (OPTIMIZE FOR (@Country_region = N''US''))';

B. Erstellen eines Planleitfadens vom Typ SQL für eine eigenständige Abfrage

Im folgenden Beispiel wird eine Plananleitung zum Abgleichen einer Abfrage in einem batch erstellt, der von einer Anwendung übermittelt wird, die die sp_executesql gespeicherte Systemprozedur verwendet.

Dies ist der Batch:

SELECT TOP 1 *
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC;

Erstellen Sie die folgende Planhinweisliste, damit kein zweiter Plan für die parallele Ausführung für diese Abfrage generiert wird:

EXEC sp_create_plan_guide
    @name = N'Guide1',
    @stmt = N'SELECT TOP 1 *
              FROM Sales.SalesOrderHeader
              ORDER BY OrderDate DESC',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = NULL,
    @hints = N'OPTION (MAXDOP 1)';

C. Erstellen eines Planleitfadens vom Typ TEMPLATE für die parametrisierte Form einer Abfrage

Im folgenden Beispiel wird eine Planhinweisliste erstellt, die mit einer beliebigen Abfrage übereinstimmt, die in einer bestimmten Form parametrisiert wird. Außerdem wird SQL Server angewiesen, die Parametrisierung der Abfrage zu erzwingen. Die folgenden beiden Abfragen sind syntaktisch gleichwertig, unterscheiden sich jedoch in ihren konstanten Literalwerten.

SELECT *
FROM AdventureWorks2022.Sales.SalesOrderHeader AS h
INNER JOIN AdventureWorks2022.Sales.SalesOrderDetail AS d
    ON h.SalesOrderID = d.SalesOrderID
WHERE h.SalesOrderID = 45639;

SELECT *
FROM AdventureWorks2022.Sales.SalesOrderHeader AS h
INNER JOIN AdventureWorks2022.Sales.SalesOrderDetail AS d
    ON h.SalesOrderID = d.SalesOrderID
WHERE h.SalesOrderID = 45640;

Hier ist die Plananleitung für die parametrisierte Form der Abfrage:

EXEC sp_create_plan_guide
    @name = N'TemplateGuide1',
    @stmt = N'SELECT * FROM AdventureWorks2022.Sales.SalesOrderHeader AS h
              INNER JOIN AdventureWorks2022.Sales.SalesOrderDetail AS d
                  ON h.SalesOrderID = d.SalesOrderID
              WHERE h.SalesOrderID = @0',
    @type = N'TEMPLATE',
    @module_or_batch = NULL,
    @params = N'@0 int',
    @hints = N'OPTION(PARAMETERIZATION FORCED)';

Im vorhergehenden Beispiel entspricht der Wert des @stmt -Parameters der parametrisierten Form der Abfrage. Die einzige zuverlässige Möglichkeit, diesen Wert für die Verwendung zu erhalten, besteht darin sp_create_plan_guide , die gespeicherte sp_get_query_template Systemprozedur zu verwenden. Das folgende Skript ruft die parametrisierte Abfrage ab und erstellt dann einen Planleitfaden.

DECLARE @stmt NVARCHAR(MAX);
DECLARE @params NVARCHAR(MAX);

EXEC sp_get_query_template N'SELECT * FROM AdventureWorks2022.Sales.SalesOrderHeader AS h
      INNER JOIN AdventureWorks2022.Sales.SalesOrderDetail AS d
          ON h.SalesOrderID = d.SalesOrderID
      WHERE h.SalesOrderID = 45639;',
    @stmt OUTPUT,
    @params OUTPUT

EXEC sp_create_plan_guide N'TemplateGuide1',
    @stmt,
    N'TEMPLATE',
    NULL,
    @params,
    N'OPTION(PARAMETERIZATION FORCED)';

Wichtig

Der Wert der konstanten Literale in dem an @stmt übergebenen sp_get_query_template -Parameter kann sich auf den Datentyp auswirken, der für den Parameter, der das Literal ersetzt, gewählt wird. Dies wiederum beeinflusst den Planhinweislistenabgleich. Möglicherweise müssen Sie mehrere Planleitfaden erstellen, um verschiedene Parameterwertbereiche zu behandeln.

D: Erstellen eines Planleitfadens für eine Abfrage, die mithilfe einer API-Cursoranforderung übermittelt wird

Planhinweislisten können Übereinstimmungen für Abfragen feststellen, die von API-Servercursorroutinen übermittelt werden. Diese Routinen umfassen sp_cursorprepare, sp_cursorprepexecund sp_cursoropen. Anwendungen, die die ADO-, OLE DB- und ODBC-APIs verwenden, interagieren häufig mit SQL Server mithilfe von API-Servercursorn. Sie können den Aufruf von API-Servercursorroutinen in SQL Server Profiler-Ablaufverfolgungen anzeigen, indem Sie das RPC:Starting Profilerablaufverfolgungsereignis anzeigen.

Angenommen, die folgenden Daten werden in einem RPC:Starting Profilerablaufverfolgungsereignis für eine Abfrage angezeigt, die Sie mit einem Planleitfaden optimieren möchten:

DECLARE @p1 INT;
SET @p1 = - 1;

DECLARE @p2 INT;
SET @p2 = 0;

DECLARE @p5 INT;
SET @p5 = 4104;

DECLARE @p6 INT;
SET @p6 = 8193;

DECLARE @p7 INT;
SET @p7 = 0;

EXEC sp_cursorprepexec @p1 OUTPUT,
    @p2 OUTPUT,
    N'@P1 varchar(255),@P2 varchar(255)',
    N'SELECT * FROM Sales.SalesOrderHeader AS h INNER JOIN Sales.SalesOrderDetail AS d ON h.SalesOrderID = d.SalesOrderID WHERE h.OrderDate BETWEEN @P1 AND @P2',
    @p5 OUTPUT,
    @p6 OUTPUT,
    @p7 OUTPUT,
    '20040101',
    '20050101'

SELECT @p1, @p2, @p5, @p6, @p7;

Sie stellen fest, dass im Plan für die SELECT-Abfrage im Aufruf von sp_cursorprepexec ein Mergejoin verwendet wird, Sie möchten jedoch ein Hashjoin verwenden. Die mithilfe von sp_cursorprepexec übermittelte Abfrage ist parametrisiert, einschließlich einer Abfragezeichenfolge und einer Parameterzeichenfolge. Sie können die folgende Planhinweisliste erstellen, um die Wahl des Plans zu ändern, indem die Abfrage- und Parameterzeichenfolgen, Zeichen für Zeichen, so wie sie angezeigt werden, im Aufruf von sp_cursorprepexec verwendet werden.

EXEC sp_create_plan_guide
    @name = N'APICursorGuide',
    @stmt = N'SELECT * FROM Sales.SalesOrderHeader AS h
              INNER JOIN Sales.SalesOrderDetail AS d
                ON h.SalesOrderID = d.SalesOrderID
              WHERE h.OrderDate BETWEEN @P1 AND @P2',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = N'@P1 varchar(255),@P2 varchar(255)',
    @hints = N'OPTION(HASH JOIN)';

Nachfolgende Ausführung dieser Abfrage durch die Anwendung wird von diesem Planleitfaden beeinflusst, und eine Hashverknnung wird verwendet, um die Abfrage zu verarbeiten.

E. Erstellen eines Planleitfadens durch Abrufen des XML-Showplans aus einem zwischengespeicherten Plan

Im folgenden Beispiel wird eine Plananleitung für eine einfache Ad-hoc-Anweisung SQL erstellt. Der gewünschte Abfrageplan für diese Anweisung wird in der Plananleitung bereitgestellt, indem der XML-Showplan für die Abfrage direkt im @hints Parameter angegeben wird. Im Beispiel wird zunächst die SQL Anweisung ausgeführt, um einen Plan im Plancache zu generieren. Für die Zwecke dieses Beispiels wird davon ausgegangen, dass der generierte Plan der gewünschte Plan ist und keine weitere Abfrageoptimierung erforderlich ist. Der XML-Showplan für die Abfrage wird durch Abfragen der sys.dm_exec_query_statsAnsichten sys.dm_exec_sql_textund dynamischen Verwaltungsansichten abgerufen und sys.dm_exec_text_query_plan der @xml_showplan Variablen zugewiesen. Die @xml_showplan -Variable wird dann im sp_create_plan_guide -Parameter an die @hints -Anweisung übergeben. Alternativ können Sie die gespeicherte Prozedur sp_create_plan_guide_from_handle verwenden, um eine Planhinweisliste aus einem Abfrageplan im Plancache zu erstellen.

USE AdventureWorks2022;
GO

SELECT City,
    StateProvinceID,
    PostalCode
FROM Person.Address
ORDER BY PostalCode DESC;
GO

DECLARE @xml_showplan NVARCHAR(MAX);

SET @xml_showplan = (
    SELECT query_plan
    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
    CROSS APPLY sys.dm_exec_text_query_plan(qs.plan_handle, DEFAULT, DEFAULT) AS qp
    WHERE st.TEXT LIKE N'SELECT City, StateProvinceID, PostalCode FROM Person.Address ORDER BY PostalCode DESC;%'
);

EXEC sp_create_plan_guide @name = N'Guide1_from_XML_showplan',
    @stmt = N'SELECT City, StateProvinceID, PostalCode FROM Person.Address ORDER BY PostalCode DESC;',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = NULL,
    @hints = @xml_showplan;
GO