Handbuch zur Architektur der AbfrageverarbeitungQuery Processing Architecture Guide

Gilt für: JaSQL Server NeinAzure SQL-Datenbank NeinAzure Synapse Analytics (SQL DW) NeinParallel Data Warehouse APPLIES TO: yesSQL Server noAzure SQL Database noAzure Synapse Analytics (SQL DW) noParallel Data Warehouse

SQL Server-Datenbank-EngineSQL Server Database Engine verarbeitet Abfragen für verschiedene Datenspeicherungsarchitekturen, z.B. lokale Tabellen, partitionierte Tabellen und serverübergreifend verteilte Tabellen.The SQL Server-Datenbank-EngineSQL Server Database Engine processes queries on various data storage architectures such as local tables, partitioned tables, and tables distributed across multiple servers. In den folgenden Themen wird erläutert, wie mit SQL ServerSQL Server Abfragen verarbeitet werden und die Wiederverwendung von Abfragen mithilfe des Zwischenspeicherns von Ausführungsplänen optimiert wird.The following topics cover how SQL ServerSQL Server processes queries and optimizes query reuse through execution plan caching.

AusführungsmodiExecution modes

Das SQL Server-Datenbank-EngineSQL Server Database Engine kann Transact-SQLTransact-SQL-Anweisungen mit zwei verschiedenen Verarbeitungsmodi verarbeiten:The SQL Server-Datenbank-EngineSQL Server Database Engine can process Transact-SQLTransact-SQL statements using two distinct processing modes:

  • ZeilenmodusausführungRow mode execution
  • BatchmodusausführungBatch mode execution

ZeilenmodusausführungRow mode execution

Die Zeilenmodusausführung ist eine Methode zur Abfrageverarbeitung, die mit herkömmlichen RDMBS-Tabellen verwendet wird, bei denen Daten im Zeilenformat gespeichert werden. Row mode execution is a query processing method used with traditional RDMBS tables, where data is stored in row format. Wenn eine Abfrage ausgeführt wird und auf Daten in Rowstore-Tabellen zugreift, lesen die Operatoren der Ausführungsstruktur und die untergeordneten Operatoren jede erforderliche Zeile in allen Spalten, die im Tabellenschema angegeben wurden.When a query is executed and accesses data in row store tables, the execution tree operators and child operators read each required row, across all the columns specified in the table schema. Für jede gelesene Zeile ruft SQL ServerSQL Server die Spalten ab, die für das Resultset erforderlich sind und auf die durch SELECT-Anweisungen, JOIN-Prädikate oder Filterprädikate verwiesen wird.From each row that is read, SQL ServerSQL Server then retrieves the columns that are required for the result set, as referenced by a SELECT statement, JOIN predicate, or filter predicate.

Hinweis

Die Zeilenmodusausführung ist für OLTP-Szenarios sehr effizient, kann jedoch beim Überprüfen großer Datenmengen (z.B. in einem Data Warehousing-Szenario) weniger effizient sein.Row mode execution is very efficient for OLTP scenarios, but can be less efficient when scanning large amounts of data, for example in Data Warehousing scenarios.

BatchmodusausführungBatch mode execution

DieBatchmodusausführung ist eine Methode zur Abfrageverarbeitung, die zum gleichzeitigen Abfragen mehrerer Zeilen (d.h. eines Batchs) verwendet wird. Batch mode execution is a query processing method used to process multiple rows together (hence the term batch). Jede Spalte innerhalb eines Batchs wird als Vektor in einem separaten Bereich des Arbeitsspeichers gespeichert. Die Batchmodusverarbeitung ist also vektorbasiert.Each column within a batch is stored as a vector in a separate area of memory, so batch mode processing is vector-based. Die Batchmodusverarbeitung verwendet ebenfalls Algorithmen, die für Mehrkern-CPUs und erhöhten Arbeitsspeicherdurchsatz bei moderner Hardware optimiert sind.Batch mode processing also uses algorithms that are optimized for the multi-core CPUs and increased memory throughput that are found on modern hardware.

Die Batchmodusausführung ist eng in das Columnstore-Speicherformat integriert und für dieses optimiert.Batch mode execution is closely integrated with, and optimized around, the columnstore storage format. Bei der Batchmodusverarbeitung kommen, sofern möglich, komprimierte Daten zum Einsatz. Zugleich werden die Austauschoperatoren beseitigt, die von der Zeilenmodusausführung verwendet werden.Batch mode processing operates on compressed data when possible, and eliminates the exchange operator used by row mode execution. Das Ergebnis ist eine bessere Parallelität und Leistung.The result is better parallelism and faster performance.

Wenn eine Abfrage im Batchmodus ausgeführt wird und auf Daten in Columnstore-Indizes zugreift, lesen die Operatoren der Ausführungsstruktur und die untergeordneten Operatoren mehrere Zeilen gleichzeitig in Spaltensegmenten.When a query is executed in batch mode, and accesses data in columnstore indexes, the execution tree operators and child operators read multiple rows together in column segments. SQL ServerSQL Server liest nur die Spalten, die für das Ergebnis erforderlich sind und auf die durch eine SELECT-Anweisung, ein JOIN-Prädikat oder ein Filterprädikat verwiesen wird.reads only the columns required for the result, as referenced by a SELECT statement, JOIN predicate, or filter predicate.
Weitere Informationen zu Columnstore-Indizes finden Sie unter Columnstore-Indizes: Architektur.For more information on columnstore indexes, see Columnstore Index Architecture.

Hinweis

Die Batchmodusausführung ist in Data Warehousing-Szenarios, bei denen große Datenmengen gelesen und aggregiert werden, sehr effizient.Batch mode execution is very efficient Data Warehousing scenarios, where large amounts of data are read and aggregated.

Verarbeiten von SQL-AnweisungenSQL Statement Processing

Die Verarbeitung einer einzelnen Transact-SQLTransact-SQL-Anweisung ist das grundlegendste Verfahren, nach dem SQL ServerSQL ServerTransact-SQLTransact-SQL-Anweisungen ausführt.Processing a single Transact-SQLTransact-SQL statement is the most basic way that SQL ServerSQL Server executes Transact-SQLTransact-SQL statements. Die Schritte, die zur Verarbeitung einer einzelnen SELECT -Anweisung verwendet werden, die nur auf lokale Basistabellen verweist (keine Sichten oder Remotetabellen), sollen das zugrunde liegende Verfahren veranschaulichen.The steps used to process a single SELECT statement that references only local base tables (no views or remote tables) illustrates the basic process.

Rangfolge logischer OperatorenLogical Operator Precedence

Wenn mehr als ein logischer Operator in einer Anweisung verwendet wird, wird NOT zuerst ausgewertet, dann AND und schließlich OR.When more than one logical operator is used in a statement, NOT is evaluated first, then AND, and finally OR. Arithmetische (und bitweise) Operatoren werden vor logischen Operatoren verarbeitet.Arithmetic, and bitwise, operators are handled before logical operators. Weitere Informationen finden Sie unter Operator Precedence (Operatorrangfolge).For more information, see Operator Precedence.

Im folgenden Beispiel ist die Color-Bedingung nur für ProductModel 21 anwendbar und nicht für ProductModel 20, weil AND Vorrang gegenüber OR hat.In the following example, the color condition pertains to product model 21, and not to product model 20, because AND has precedence over OR.

SELECT ProductID, ProductModelID
FROM Production.Product
WHERE ProductModelID = 20 OR ProductModelID = 21
  AND Color = 'Red';
GO

Sie können die Bedeutung der Abfrage ändern, indem Sie durch Hinzufügen von Klammern veranlassen, dass der Operator OR zuerst ausgewertet wird.You can change the meaning of the query by adding parentheses to force evaluation of the OR first. Die folgende Abfrage findet nur Produkte unter den Modellen 20 und 21, deren Farbe „red“ (rot) ist.The following query finds only products under models 20 and 21 that are red.

SELECT ProductID, ProductModelID
FROM Production.Product
WHERE (ProductModelID = 20 OR ProductModelID = 21)
  AND Color = 'Red';
GO

Die Verwendung von Klammern kann auch dann empfehlenswert sein, wenn diese nicht unbedingt erforderlich sind, da sie die Übersichtlichkeit von Abfragen verbessern und zudem die Wahrscheinlichkeit von Flüchtigkeitsfehlern verringern, die sich aus der Rangfolge der Operatorenauswertung ergeben.Using parentheses, even when they are not required, can improve the readability of queries, and reduce the chance of making a subtle mistake because of operator precedence. Die Leistung wird durch den Einsatz von Klammern nicht wesentlich beeinträchtigt.There is no significant performance penalty in using parentheses. Das folgende Beispiel ist leichter zu lesen als das ursprüngliche Beispiel, obwohl sie syntaktisch übereinstimmen:The following example is more readable than the original example, although they are syntactically the same.

SELECT ProductID, ProductModelID
FROM Production.Product
WHERE ProductModelID = 20 OR (ProductModelID = 21
  AND Color = 'Red');
GO

Optimieren von SELECT-AnweisungenOptimizing SELECT statements

Eine SELECT -Anweisung ist nicht prozedural; sie gibt nicht die genauen Schritte vor, die der Datenbankserver verwenden soll, um die angeforderten Daten abzurufen.A SELECT statement is non-procedural; it does not state the exact steps that the database server should use to retrieve the requested data. Dies bedeutet, dass der Datenbankserver die Anweisung analysieren muss, um das effizienteste Verfahren zum Extrahieren der angeforderten Daten zu ermitteln.This means that the database server must analyze the statement to determine the most efficient way to extract the requested data. Dieser Vorgang wird als Optimieren der SELECT -Anweisung bezeichnet.This is referred to as optimizing the SELECT statement. Die Komponente, die ihn durchführt, wird als Abfrageoptimierer bezeichnet.The component that does this is called the Query Optimizer. Die Eingaben für den Abfrageoptimierer bestehen aus der Abfrage, dem Datenbankschema (Tabellen- und Indexdefinitionen) und den Datenbankstatistiken.The input to the Query Optimizer consists of the query, the database schema (table and index definitions), and the database statistics. Die Ausgabe des Abfrageoptimierers ist ein Abfrageausführungsplan, der manchmal auch als Abfrageplan oder einfach nur als Plan bezeichnet wird.The output of the Query Optimizer is a query execution plan, sometimes referred to as a query plan or just a plan. Der Inhalt eines Abfrageplans wird ausführlicher an späterer Stelle in diesem Thema beschrieben.The contents of a query plan are described in more detail later in this topic.

Die Ein- und Ausgaben des Abfrageoptimierers während der Optimierung einer einzelnen SELECT-Anweisung werden in folgendem Diagramm dargestellt:The inputs and outputs of the Query Optimizer during optimization of a single SELECT statement are illustrated in the following diagram:

query_processor_io

Eine SELECT -Anweisung definiert lediglich Folgendes:A SELECT statement defines only the following:

  • Das Format des Resultsets.The format of the result set. Dieses wird meistens in der Auswahlliste angegeben.This is specified mostly in the select list. Das endgültige Format des Resultsets wird jedoch auch von anderen Klauseln, wie z.B. ORDER BY und GROUP BY , beeinflusst.However, other clauses such as ORDER BY and GROUP BY also affect the final form of the result set.
  • Die Tabellen, die die Quelldaten enthalten.The tables that contain the source data. Dies wird in der FROM -Klausel angegeben.This is specified in the FROM clause.
  • Die logischen Beziehungen zwischen den Tabellen, die im Rahmen der SELECT -Anweisung relevant sind.How the tables are logically related for the purposes of the SELECT statement. Diese werden in den Joinspezifikationen definiert, die in der WHERE -Klausel oder in einer ON -Klausel, die auf FROMfolgt, auftreten können.This is defined in the join specifications, which may appear in the WHERE clause or in an ON clause following FROM.
  • Die Bedingungen, die die Zeilen in den Quelltabellen erfüllen müssen, um für die SELECT -Anweisung qualifiziert zu sein.The conditions that the rows in the source tables must satisfy to qualify for the SELECT statement. Diese werden in den WHERE - und HAVING -Klauseln angegeben.These are specified in the WHERE and HAVING clauses.

In einem Abfrageausführungsplan wird Folgendes definiert:A query execution plan is a definition of the following:

  • Die Reihenfolge des Zugriffs auf die Quelltabellen.The sequence in which the source tables are accessed.
    In der Regel gibt es viele Abfolgen, in denen der Datenbankserver auf die Basistabellen zugreifen kann, um das Resultset zu erstellen.Typically, there are many sequences in which the database server can access the base tables to build the result set. Wenn die SELECT -Anweisung z.B. auf drei Tabellen verweist, könnte der Datenbankserver zuerst auf TableAzugreifen, dann die Daten aus TableA verwenden, um die entsprechenden Zeilen aus TableBzu extrahieren, und dann die Daten aus TableB verwenden, um Daten aus TableCzu extrahieren.For example, if the SELECT statement references three tables, the database server could first access TableA, use the data from TableA to extract matching rows from TableB, and then use the data from TableB to extract data from TableC. Die anderen Abfolgen, in denen der Datenbankserver auf die Tabellen zugreifen kann, lauten:The other sequences in which the database server could access the tables are:
    TableC, TableB, TableAoder , , , or
    TableB, TableA, TableCoder , , , or
    TableB, TableC, TableAoder , , , or
    TableC, TableA, TableB

  • Die Methoden, die verwendet werden, um Daten aus den einzelnen Tabellen zu extrahieren.The methods used to extract data from each table.
    Für den Zugriff auf die Daten in den einzelnen Tabellen gibt es in der Regel unterschiedliche Methoden.Generally, there are different methods for accessing the data in each table. Wenn nur wenige Zeilen mit bestimmten Schlüsselwerten erforderlich sind, kann der Datenbankserver einen Index verwenden.If only a few rows with specific key values are required, the database server can use an index. Wenn alle Zeilen der Tabelle erforderlich sind, kann der Datenbankserver die Indizes übergehen und einen Tabellenscan ausführen.If all the rows in the table are required, the database server can ignore the indexes and perform a table scan. Wenn alle Zeilen einer Tabelle erforderlich sind, die Tabelle jedoch über einen Index verfügt, dessen Schlüsselspalten in einer ORDER BY-Klausel verwendet werden, kann durch die Durchführung eines Indexscans anstelle eines Tabellenscans eine andere Sortierung des Resultsets gespeichert werden.If all the rows in a table are required but there is an index whose key columns are in an ORDER BY, performing an index scan instead of a table scan may save a separate sort of the result set. Wenn es sich um eine sehr kleine Tabelle handelt, können Tabellenscans die effizienteste Methode für fast alle Zugriffe auf die Tabelle darstellen.If a table is very small, table scans may be the most efficient method for almost all access to the table.

Der Vorgang, in dessen Verlauf ein bestimmter Ausführungsplan aus einer Anzahl möglicher Ausführungspläne ausgewählt wird, wird Optimierung genannt.The process of selecting one execution plan from potentially many possible plans is referred to as optimization. Der Abfrageoptimierer stellt eine der wichtigsten Komponenten eines SQL-Datenbanksystems dar.The Query Optimizer is one of the most important components of a SQL database system. Der Abfrageoptimierer erzeugt zwar den zusätzlichen Aufwand, um die Abfrage analysieren und einen Plan auswählen zu können, ein Vielfaches dieses Aufwands wird jedoch normalerweise dadurch eingespart, dass der Abfrageoptimierer einen effizienten Ausführungsplan auswählt.While some overhead is used by the Query Optimizer to analyze the query and select a plan, this overhead is typically saved several-fold when the Query Optimizer picks an efficient execution plan. Nehmen Sie z. B. an, zwei Bauunternehmer erhalten dieselben Konstruktionszeichnungen für ein Haus.For example, two construction companies can be given identical blueprints for a house. Wenn nun das eine Unternehmen zunächst einige Tage darauf verwendet, den Bau des Hauses detailliert zu planen, das andere Unternehmen jedoch sofort und ohne weitere Planung mit dem Bau des Hauses beginnt, ist es mehr als wahrscheinlich, dass das erste Unternehmen, das sich Zeit für die Planung des Projekts nimmt, den Bau des Hauses zuerst abschließen wird.If one company spends a few days at the beginning to plan how they will build the house, and the other company begins building without planning, the company that takes the time to plan their project will probably finish first.

Der Abfrageoptimierer von SQL ServerSQL Server arbeitet kostenorientiert.The SQL ServerSQL Server Query Optimizer is a cost-based Query Optimizer. Jeder denkbare Ausführungsplan verfügt über zugeordnete Kosten hinsichtlich des Umfangs der benötigten Verarbeitungsressourcen.Each possible execution plan has an associated cost in terms of the amount of computing resources used. Der Abfrageoptimierer muss die möglichen Pläne analysieren und den Plan auswählen, der die geringsten geschätzten Kosten verursacht.The Query Optimizer must analyze the possible plans and choose the one with the lowest estimated cost. Einige komplexe SELECT -Anweisungen verfügen über mehrere Tausend mögliche Ausführungspläne.Some complex SELECT statements have thousands of possible execution plans. In einem solchen Fall werden nicht alle denkbaren Kombinationen vom Abfrageoptimierer analysiert.In these cases, the Query Optimizer does not analyze all possible combinations. Stattdessen werden komplexe Algorithmen verwendet, um einen Ausführungsplan zu ermitteln, dessen Kosten sich in vernünftigem Rahmen an die möglichen Mindestkosten annähern.Instead, it uses complex algorithms to find an execution plan that has a cost reasonably close to the minimum possible cost.

Der Abfrageoptimierer von SQL ServerSQL Server wählt nicht nur den Ausführungsplan aus, der die geringsten Kosten bezüglich der benötigten Ressourcen verursacht. Stattdessen wird der Plan ausgewählt, der die Ergebnisse so schnell wie möglich an den Benutzer zurückgibt und dabei Kosten für Ressourcen in vertretbarem Maß verursacht.The SQL ServerSQL Server Query Optimizer does not choose only the execution plan with the lowest resource cost; it chooses the plan that returns results to the user with a reasonable cost in resources and that returns the results the fastest. Für die parallele Verarbeitung einer Abfrage werden in der Regel mehr Ressourcen verwendet als für die serielle Verarbeitung, die Abfrageausführung wird jedoch schneller beendet.For example, processing a query in parallel typically uses more resources than processing it serially, but completes the query faster. Der SQL ServerSQL Server-Abfrageoptimierer verwendet einen Plan mit paralleler Ausführung, um Ergebnisse zurückzugeben, wenn sich dies nicht negativ auf die Serverlast auswirkt.The SQL ServerSQL Server Query Optimizer will use a parallel execution plan to return results if the load on the server will not be adversely affected.

Der SQL ServerSQL Server-Abfrageoptimierer stützt sich bei der Schätzung der Ressourcenkosten, die durch unterschiedliche Methoden zum Extrahieren von Informationen aus einer Tabelle oder einem Index verursacht werden, auf Verteilungsstatistiken.The SQL ServerSQL Server Query Optimizer relies on distribution statistics when it estimates the resource costs of different methods for extracting information from a table or index. Die Verteilungsstatistiken werden für Spalten und Indizes gespeichert und enthalten Informationen über die Dichte1 der zugrunde liegenden Daten.Distribution statistics are kept for columns and indexes, and hold information on the density1 of the underlying data. Dies dient dazu, die Selektivität der Werte in einem bestimmten Index oder einer bestimmten Spalte zu kennzeichnen.This is used to indicate the selectivity of the values in a particular index or column. In einer Tabelle für Autos stammen z. B. viele Autos von demselben Hersteller, jedes Auto verfügt jedoch über eine eindeutige Fahrzeugnummer.For example, in a table representing cars, many cars have the same manufacturer, but each car has a unique vehicle identification number (VIN). Ein Index für das VIN-Objekt weist eine höhere Selektivität auf als ein Index für den Hersteller, da „VIN“ eine niedrigere Dichte als „Hersteller“ aufweist.An index on the VIN is more selective than an index on the manufacturer, because VIN has lower density then manufacturer. Wenn die Indexstatistiken nicht auf dem aktuellen Stand sind, wählt der Abfrageoptimierer möglicherweise nicht den Plan aus, der für den aktuellen Status der Tabelle am besten geeignet ist.If the index statistics are not current, the Query Optimizer may not make the best choice for the current state of the table. Weitere Informationen zu Dichten finden Sie unter Statistik.For more information about densities, see Statistics.

1 Dichte definiert die Verteilung von eindeutigen Werten, die in den Daten vorhanden sind, oder die durchschnittliche Anzahl doppelter Werte für eine bestimmte Spalte. 1 Density defines the distribution of unique values that exist in the data, or the average number of duplicate values for a given column. Bei einer Verringerung der Dichte erhöht sich die Selektivität eines Werts.As density decreases, selectivity of a value increases.

Der SQL ServerSQL Server-Abfrageoptimierer ist deshalb so wichtig, weil er es dem Datenbankserver ermöglicht, dynamische Anpassungen an geänderte Bedingungen in der Datenbank vorzunehmen, ohne dass eine Eingabe durch einen Programmierer oder Datenbankadministrator erforderlich ist.The SQL ServerSQL Server Query Optimizer is important because it enables the database server to adjust dynamically to changing conditions in the database without requiring input from a programmer or database administrator. Programmierer können sich somit darauf konzentrieren, das endgültige Ergebnis der Abfrage zu beschreiben.This enables programmers to focus on describing the final result of the query. Sie können sich darauf verlassen, dass der SQL ServerSQL Server-Abfrageoptimierer bei jeder Ausführung der Anweisung einen effizienten Ausführungsplan auf der Basis des aktuellen Status der Datenbank erstellt.They can trust that the SQL ServerSQL Server Query Optimizer will build an efficient execution plan for the state of the database every time the statement is run.

Verarbeiten einer SELECT-AnweisungProcessing a SELECT Statement

SQL ServerSQL Server führt zur Verarbeitung einer einzelnen SELECT-Anweisung die folgenden grundlegenden Schritte aus:The basic steps that SQL ServerSQL Server uses to process a single SELECT statement include the following:

  1. Der Parser scannt die SELECT -Anweisung und spaltet sie in ihre logischen Einheiten auf, wie z.B. Schlüsselwörter, Ausdrücke, Operatoren und Bezeichner.The parser scans the SELECT statement and breaks it into logical units such as keywords, expressions, operators, and identifiers.
  2. Eine Abfragestruktur, manchmal auch Sequenzstruktur genannt, wird erstellt, die die logischen Schritte beschreibt, die für die Transformation der Quelldaten in das für das Resultset benötigte Format erforderlich sind.A query tree, sometimes referred to as a sequence tree, is built describing the logical steps needed to transform the source data into the format required by the result set.
  3. Der Abfrageoptimierer analysiert verschiedene Arten des Zugriffs auf die Quelltabellen.The Query Optimizer analyzes different ways the source tables can be accessed. Anschließend wählt er die Reihenfolge der Schritte aus, mit denen die Ergebnisse am schnellsten mithilfe möglichst weniger Ressourcen zurückgegeben werden.It then selects the series of steps that returns the results fastest while using fewer resources. Die Abfragestruktur wird aktualisiert, um diese genaue Reihenfolge von Schritten aufzuzeichnen.The query tree is updated to record this exact series of steps. Die endgültige, optimierte Version der Abfragestruktur wird als Ausführungsplan bezeichnet.The final, optimized version of the query tree is called the execution plan.
  4. Die relationale Engine beginnt mit der Ausführung des Ausführungsplans.The relational engine starts executing the execution plan. Während der Verarbeitung von Schritten, für die Daten aus den Basistabellen erforderlich sind, fordert die relationale Engine an, dass die Speicher-Engine die Daten aus den Rowsets übergibt, die durch die relationale Engine angefordert wurden.As the steps that require data from the base tables are processed, the relational engine requests that the storage engine pass up data from the rowsets requested from the relational engine.
  5. Die relationale Engine transformiert die Daten, die von der Speicher-Engine zurückgegeben werden, in das für das Resultset definierte Format und gibt das Resultset an den Client zurück.The relational engine processes the data returned from the storage engine into the format defined for the result set and returns the result set to the client.

Reduktion konstanter Ausdrücke und Auswertung von Ausdrücken

Constant Folding and Expression Evaluation SQL ServerSQL Server wertet bestimmte konstante Ausdrücke frühzeitig aus, um die Abfrageleistung zu steigern.evaluates some constant expressions early to improve query performance. Dies wird als Reduktion konstanter Ausdrücke bezeichnet.This is referred to as constant folding. Eine Konstante ist ein Transact-SQLTransact-SQL-Literal, z. B. 3, „ABC“, „2005-12-31“, 1.0e3 oder 0x12345678.A constant is a Transact-SQLTransact-SQL literal, such as 3, 'ABC', '2005-12-31', 1.0e3, or 0x12345678.

Zur Kompilierzeit reduzierbare AusdrückeFoldable Expressions

SQL ServerSQL Server verwendet die Reduktion konstanter Ausdrücke mit den folgenden Ausdruckstypen:uses constant folding with the following types of expressions:

  • Arithmetische Ausdrücke wie 1+1, 5/3*2, die nur Konstanten enthalten.Arithmetic expressions, such as 1+1, 5/3*2, that contain only constants.
  • Logische Ausdrücke wie 1=1 und 1>2 AND 3>4, die nur Konstanten enthalten.Logical expressions, such as 1=1 and 1>2 AND 3>4, that contain only constants.
  • Integrierte Funktionen, die von SQL ServerSQL Server zur Kompilierzeit reduziert werden können, einschließlich CAST und CONVERT.Built-in functions that are considered foldable by SQL ServerSQL Server, including CAST and CONVERT. Im Allgemeinen gilt eine systeminterne Funktion als zur Kompilierzeit reduzierbar, wenn sie ausschließlich aus Eingaben besteht – ohne weitere kontextbezogene Informationen wie SET-Optionen, Spracheinstellungen, Datenbankoptionen oder Verschlüsselungsschlüssel.Generally, an intrinsic function is foldable if it is a function of its inputs only and not other contextual information, such as SET options, language settings, database options, and encryption keys. Nicht deterministische Funktionen sind nicht zur Kompilierzeit reduzierbar.Nondeterministic functions are not foldable. Deterministische integrierte Funktionen sind bis auf einige Ausnahmen zur Kompilierzeit reduzierbar.Deterministic built-in functions are foldable, with some exceptions.

Hinweis

Eine Ausnahme sind große Objekte.An exception is made for large object types. Wenn der Ausgabetyp des Reduktionsprozesses ein großes Objekt (text, image, nvarchar(max), varchar(max) oder varbinary(max)) ist, reduziert SQL ServerSQL Server den Ausdruck nicht zur Kompilierzeit.If the output type of the folding process is a large object type (text, image, nvarchar(max), varchar(max), or varbinary(max)), then SQL ServerSQL Server does not fold the expression.

Nicht zur Kompilierzeit reduzierbare AusdrückeNonfoldable Expressions

Alle anderen Ausdruckstypen können nicht zur Kompilierzeit reduziert werden.All other expression types are not foldable. Dabei handelt es sich insbesondere um folgende Ausdrücke:In particular, the following types of expressions are not foldable:

  • Nicht konstante Ausdrücke, wie z. B. Ausdrücke, deren Ergebnisse vom Wert einer Spalte abhängig sind.Nonconstant expressions such as an expression whose result depends on the value of a column.
  • Ausdrücke, deren Ergebnisse von einer lokalen Variable bzw. einem lokalen Parameter abhängig sind, wie z. B. @x.Expressions whose results depend on a local variable or parameter, such as @x.
  • Nicht deterministische Funktionen.Nondeterministic functions.
  • Benutzerdefinierte Funktionen (Transact-SQLTransact-SQL und CLR).User-defined functions (both Transact-SQLTransact-SQL and CLR).
  • Ausdrücke, deren Ergebnisse von Spracheinstellungen abhängig sind.Expressions whose results depend on language settings.
  • Ausdrücke, deren Ergebnisse von SET-Optionen abhängig sind.Expressions whose results depend on SET options.
  • Ausdrücke, deren Ergebnisse von Serverkonfigurationsoptionen abhängig sind.Expressions whose results depend on server configuration options.

Beispiele für zur Kompilierzeit reduzierbare und nicht zur Kompilierzeit reduzierbare konstante AusdrückeExamples of Foldable and Nonfoldable Constant Expressions

Betrachten Sie die folgende Abfrage:Consider the following query:

SELECT *
FROM Sales.SalesOrderHeader AS s 
INNER JOIN Sales.SalesOrderDetail AS d 
ON s.SalesOrderID = d.SalesOrderID
WHERE TotalDue > 117.00 + 1000.00;

Wird für diese Abfrage die PARAMETERIZATION-Datenbankoption nicht auf FORCEDfestgelegt, wird der Ausdruck 117.00 + 1000.00 ausgewertet und durch sein Ergebnis (1117.00) ersetzt, bevor die Abfrage kompiliert wird.If the PARAMETERIZATION database option is not set to FORCED for this query, then the expression 117.00 + 1000.00 is evaluated and replaced by its result, 1117.00, before the query is compiled. Die Vorteile dieser Reduktion des konstanten Ausdrucks sind folgende:Benefits of this constant folding include the following:

  • Der Ausdruck muss zur Laufzeit nicht mehrmals ausgewertet werden.The expression does not have to be evaluated repeatedly at run time.
  • Der durch die Auswertung des Ausdrucks erhaltene Wert wird vom Abfrageoptimierer verwendet, um die Größe des Resultsets der Teilabfrage TotalDue > 117.00 + 1000.00 zu schätzen.The value of the expression after it is evaluated is used by the Query Optimizer to estimate the size of the result set of the portion of the query TotalDue > 117.00 + 1000.00.

Wenn dbo.f jedoch eine skalare benutzerdefinierte Funktion ist, wird der Ausdruck dbo.f(100) nicht zur Kompilierzeit reduziert, da SQL ServerSQL Server keine benutzerdefinierten Funktionen zur Kompilierzeit reduziert, auch wenn sie deterministisch sind.On the other hand, if dbo.f is a scalar user-defined function, the expression dbo.f(100) is not folded, because SQL ServerSQL Server does not fold expressions that involve user-defined functions, even if they are deterministic. Weitere Informationen zur Parametrisierung finden Sie unter Erzwungene Parametrisierung weiter unten in diesem Artikel.For more information on parameterization, see Forced Parameterization later in this article.

Auswertung von Ausdrücken

Expression Evaluation Außerdem werden bestimmte Ausdrücke, die zwar nicht zur Kompilierzeit ausgewertet werden, deren Argumente jedoch zur Kompilierzeit bekannt sind – unabhängig davon, ob es sich bei den Argumenten um Parameter oder Konstanten handelt – hinsichtlich der Größe ihrer Resultsets (Kardinalität) geschätzt. Dieser Vorgang ist ein Bestandteil des Abfrageoptimierers.In addition, some expressions that are not constant folded but whose arguments are known at compile time, whether the arguments are parameters or constants, are evaluated by the result-set size (cardinality) estimator that is part of the optimizer during optimization.

Insbesondere werden folgende integrierte Funktionen und spezielle Operatoren zur Kompilierzeit ausgewertet, wenn alle diesbezüglichen Eingaben bekannt sind: UPPER, LOWER, RTRIM, DATEPART( YY only ), GETDATE, CAST und CONVERT.Specifically, the following built-in functions and special operators are evaluated at compile time if all their inputs are known: UPPER, LOWER, RTRIM, DATEPART( YY only ), GETDATE, CAST, and CONVERT. Die folgenden Operatoren werden ebenfalls zur Kompilierzeit ausgewertet, wenn alle diesbezüglichen Eingaben bekannt sind:The following operators are also evaluated at compile time if all their inputs are known:

  • Arithmetische Operatoren: +, -, *, /, unär -Arithmetic operators: +, -, *, /, unary -
  • Logische Operatoren: AND, OR und NOTLogical Operators: AND, OR, NOT
  • Vergleichsoperatoren: <, >, <=, >=, <>, LIKE, IS NULL, IS NOT NULLComparison operators: <, >, <=, >=, <>, LIKE, IS NULL, IS NOT NULL

Während der Kardinalitätsschätzung wertet der Abfrageoptimierer keine anderen Funktionen oder Operatoren aus.No other functions or operators are evaluated by the Query Optimizer during cardinality estimation.

Beispiele für die Ausdrucksauswertung zur KompilierzeitExamples of Compile-Time Expression Evaluation

Sehen Sie sich diese gespeicherte Prozedur an:Consider this stored procedure:

USE AdventureWorks2014;
GO
CREATE PROCEDURE MyProc( @d datetime )
AS
SELECT COUNT(*)
FROM Sales.SalesOrderHeader
WHERE OrderDate > @d+1;

Während der Optimierung der SELECT-Anweisung der Prozedur versucht der Abfrageoptimierer, die erwartete Kardinalität des Resultsets für die Bedingung OrderDate > @d+1 auszuwerten.During optimization of the SELECT statement in the procedure, the Query Optimizer tries to evaluate the expected cardinality of the result set for the condition OrderDate > @d+1. Der Ausdruck @d+1 kann nicht zur Kompilierzeit reduziert werden, da @d ein Parameter ist.The expression @d+1 is not constant-folded, because @d is a parameter. Zum Zeitpunkt der Optimierung ist der Wert dieses Parameters jedoch bekannt.However, at optimization time, the value of the parameter is known. Dadurch kann der Abfrageoptimierer die Größe des Resultsets genau schätzen, was zur Auswahl des optimalen Abfrageplans beiträgt.This allows the Query Optimizer to accurately estimate the size of the result set, which helps it select a good query plan.

Betrachten Sie nun ein ähnliches Beispiel, in dem jedoch @d2 durch eine lokale Variable, @d+1, ersetzt wird, und der Ausdruck statt in einer Abfrage in einer SET-Anweisung ausgewertet wird.Now consider an example similar to the previous one, except that a local variable @d2 replaces @d+1 in the query and the expression is evaluated in a SET statement instead of in the query.

USE AdventureWorks2014;
GO
CREATE PROCEDURE MyProc2( @d datetime )
AS
BEGIN
DECLARE @d2 datetime
SET @d2 = @d+1
SELECT COUNT(*)
FROM Sales.SalesOrderHeader
WHERE OrderDate > @d2
END;

Wenn die SELECT-Anweisung in MyProc2 in SQL ServerSQL Server optimiert wird, ist der Wert von @d2 nicht bekannt.When the SELECT statement in MyProc2 is optimized in SQL ServerSQL Server, the value of @d2 is not known. Daher verwendet der Abfrageoptimierer eine Standardschätzung für die Selektivität von OrderDate > @d2 (in diesem Fall 30 Prozent).Therefore, the Query Optimizer uses a default estimate for the selectivity of OrderDate > @d2, (in this case 30 percent).

Verarbeiten anderer AnweisungenProcessing Other Statements

Die zuvor beschriebenen grundlegenden Schritte für die Verarbeitung einer SELECT-Anweisung gelten ebenfalls für andere Transact-SQLTransact-SQL-Anweisungen, z. B. INSERT, UPDATE und DELETE.The basic steps described for processing a SELECT statement apply to other Transact-SQLTransact-SQL statements such as INSERT, UPDATE, and DELETE. UPDATE - und DELETE -Anweisungen müssen sich auf die Gruppe von Zeilen beziehen, die geändert bzw. gelöscht werden soll.UPDATE and DELETE statements both have to target the set of rows to be modified or deleted. Der Vorgang zum Identifizieren dieser Zeilen ist der gleiche Vorgang, der zum Identifizieren der Quellzeilen verwendet wird, die einen Beitrag zum Resultset einer SELECT -Anweisung leisten.The process of identifying these rows is the same process used to identify the source rows that contribute to the result set of a SELECT statement. Die UPDATE- und INSERT-Anweisung können eingebettete SELECT-Anweisungen enthalten, welche die Datenwerte bereitstellen, die aktualisiert oder eingefügt werden sollen.The UPDATE and INSERT statements may both contain embedded SELECT statements that provide the data values to be updated or inserted.

Sogar DDL-Anweisungen (Data Definition Language, Datendefinitionssprache), wie z.B. CREATE PROCEDURE oder ALTER TABLE, werden letztendlich in eine Folge relationaler Operationen aufgelöst, die für die Systemkatalogtabellen und manchmal (wie bei ALTER TABLE ADD COLUMN) auch für die Datentabellen ausgeführt werden.Even Data Definition Language (DDL) statements, such as CREATE PROCEDURE or ALTER TABLE, are ultimately resolved to a series of relational operations on the system catalog tables and sometimes (such as ALTER TABLE ADD COLUMN) against the data tables.

ArbeitstabellenWorktables

Soll eine logische Operation ausgeführt werden, die in einer Transact-SQLTransact-SQL-Anweisung angegeben wurde, muss die relationale Engine ggf. eine Arbeitstabelle erstellen.The relational engine may need to build a worktable to perform a logical operation specified in an Transact-SQLTransact-SQL statement. Arbeitstabellen sind interne Tabellen, die zum Speichern von Zwischenergebnissen verwendet werden.Worktables are internal tables that are used to hold intermediate results. Arbeitstabellen werden für bestimmte GROUP BY-, ORDER BY- oder UNION -Abfragen generiert.Worktables are generated for certain GROUP BY, ORDER BY, or UNION queries. Wenn z.B. eine ORDER BY-Klausel auf Spalten verweist, die nicht durch Indizes erfasst werden, muss die relationale Engine eventuell eine Arbeitstabelle generieren, um das Resultset in der angeforderten Reihenfolge sortieren zu können.For example, if an ORDER BY clause references columns that are not covered by any indexes, the relational engine may need to generate a worktable to sort the result set into the order requested. Arbeitstabellen werden mitunter auch als Spool-Speicher verwendet, die vorübergehend das Ergebnis der Ausführung eines Teils eines Abfrageplans aufnehmen.Worktables are also sometimes used as spools that temporarily hold the result of executing a part of a query plan. Arbeitstabellen werden in tempdb erstellt und automatisch wieder gelöscht, sobald sie nicht mehr benötigt werden.Worktables are built in tempdb and are dropped automatically when they are no longer needed.

SichtauflösungView Resolution

Der SQL ServerSQL Server-Abfrageprozessor behandelt indizierte und nicht indizierte Sichten unterschiedlich:The SQL ServerSQL Server query processor treats indexed and nonindexed views differently:

  • Die Zeilen einer indizierten Sicht werden in der Datenbank in demselben Format wie eine Tabelle gespeichert.The rows of an indexed view are stored in the database in the same format as a table. Wenn sich der Abfrageoptimierer entscheidet, eine indizierte Sicht in einem Abfrageplan zu verwenden, wird die indizierte Sicht auf die gleiche Weise wie eine Basistabelle behandelt.If the Query Optimizer decides to use an indexed view in a query plan, the indexed view is treated the same way as a base table.
  • Nur die Definition einer nicht indizierten Sicht wird gespeichert, nicht die Zeilen der Sicht.Only the definition of a nonindexed view is stored, not the rows of the view. Der Abfrageoptimierer nimmt die Logik aus der Sichtdefinition in den Ausführungsplan auf, den er für die Transact-SQLTransact-SQL-Anweisung erstellt, die auf die nicht indizierte Sicht verweist.The Query Optimizer incorporates the logic from the view definition into the execution plan it builds for the Transact-SQLTransact-SQL statement that references the nonindexed view.

Die Logik, anhand derer der SQL ServerSQL Server-Abfrageoptimierer entscheidet, wann eine indizierte Sicht verwendet werden soll, ist mit der Logik vergleichbar, anhand derer ermittelt wird, wann ein Index für eine Tabelle verwendet wird.The logic used by the SQL ServerSQL Server Query Optimizer to decide when to use an indexed view is similar to the logic used to decide when to use an index on a table. Wenn die Daten in der indizierten Sicht die gesamte oder einen Teil der Transact-SQLTransact-SQL-Anweisung erfüllen und der Abfrageoptimierer ermittelt, dass ein Index für die Sicht der Zugriffspfad mit den geringsten Kosten ist, wählt der Abfrageoptimierer den Index unabhängig davon aus, ob im Namen der Abfrage auf die Sicht verwiesen wird.If the data in the indexed view covers all or part of the Transact-SQLTransact-SQL statement, and the Query Optimizer determines that an index on the view is the low-cost access path, the Query Optimizer will choose the index regardless of whether the view is referenced by name in the query.

Wenn eine Transact-SQLTransact-SQL-Anweisung auf eine nicht indizierte Sicht verweist, analysieren der Parser und der Abfrageoptimierer die Quelle sowohl der Transact-SQLTransact-SQL-Anweisung als auch der Sicht und lösen sie dann zu einem einzigen Ausführungsplan auf.When an Transact-SQLTransact-SQL statement references a nonindexed view, the parser and Query Optimizer analyze the source of both the Transact-SQLTransact-SQL statement and the view and then resolve them into a single execution plan. Es gibt nicht einen Plan für die Transact-SQLTransact-SQL-Anweisung und einen weiteren Plan für die Sicht.There is not one plan for the Transact-SQLTransact-SQL statement and a separate plan for the view.

Nehmen Sie z. B. an, dass die folgende Sicht verwendet wird:For example, consider the following view:

USE AdventureWorks2014;
GO
CREATE VIEW EmployeeName AS
SELECT h.BusinessEntityID, p.LastName, p.FirstName
FROM HumanResources.Employee AS h 
JOIN Person.Person AS p
ON h.BusinessEntityID = p.BusinessEntityID;
GO

Von dieser Sicht ausgehend führen die beiden folgenden Transact-SQLTransact-SQL-Anweisungen die gleichen Vorgänge für die Basistabellen aus und erzeugen identische Ergebnisse:Based on this view, both of these Transact-SQLTransact-SQL statements perform the same operations on the base tables and produce the same results:

/* SELECT referencing the EmployeeName view. */
SELECT LastName AS EmployeeLastName, SalesOrderID, OrderDate
FROM AdventureWorks2014.Sales.SalesOrderHeader AS soh
JOIN AdventureWorks2014.dbo.EmployeeName AS EmpN
ON (soh.SalesPersonID = EmpN.BusinessEntityID)
WHERE OrderDate > '20020531';

/* SELECT referencing the Person and Employee tables directly. */
SELECT LastName AS EmployeeLastName, SalesOrderID, OrderDate
FROM AdventureWorks2014.HumanResources.Employee AS e 
JOIN AdventureWorks2014.Sales.SalesOrderHeader AS soh
ON soh.SalesPersonID = e.BusinessEntityID
JOIN AdventureWorks2014.Person.Person AS p
ON e.BusinessEntityID =p.BusinessEntityID
WHERE OrderDate > '20020531';

Durch die SQL ServerSQL Server Management Studio-Showplanfunktion wird deutlich, dass die relationale Engine für beide SELECT-Anweisungen denselben Ausführungsplan erstellt.The SQL ServerSQL Server Management Studio Showplan feature shows that the relational engine builds the same execution plan for both of these SELECT statements.

Verwenden von Hinweisen mit SichtenUsing Hints with Views

Hinweise, die für Sichten in einer Abfrage gespeichert werden, können zu Konflikten mit anderen Hinweisen führen, die beim Erweitern der Sicht für den Zugriff auf ihre Basistabellen erkannt werden.Hints that are placed on views in a query may conflict with other hints that are discovered when the view is expanded to access its base tables. Wenn das passiert, gibt die Abfrage einen Fehler zurück.When this occurs, the query returns an error. Angenommen, die folgende Sicht enthält einen Tabellenhinweis in ihrer Definition:For example, consider the following view that contains a table hint in its definition:

USE AdventureWorks2014;
GO
CREATE VIEW Person.AddrState WITH SCHEMABINDING AS
SELECT a.AddressID, a.AddressLine1, 
    s.StateProvinceCode, s.CountryRegionCode
FROM Person.Address a WITH (NOLOCK), Person.StateProvince s
WHERE a.StateProvinceID = s.StateProvinceID;

Nehmen Sie nun an, dass die folgende Abfrage eingegeben wird:Now suppose you enter this query:

SELECT AddressID, AddressLine1, StateProvinceCode, CountryRegionCode
FROM Person.AddrState WITH (SERIALIZABLE)
WHERE StateProvinceCode = 'WA';

Die Abfrage erzeugt einen Fehler, weil der SERIALIZABLE -Hinweis, der für die Person.AddrState -Sicht in der Abfrage angewendet wird, an die beiden Tabellen Person.Address und Person.StateProvince in der Sicht weitergegeben wird, wenn diese erweitert wird.The query fails, because the hint SERIALIZABLE that is applied on view Person.AddrState in the query is propagated to both tables Person.Address and Person.StateProvince in the view when it is expanded. Das Erweitern der Sicht legt jedoch außerdem den NOLOCK -Hinweis für Person.Addressoffen.However, expanding the view also reveals the NOLOCK hint on Person.Address. Da die SERIALIZABLE - und NOLOCK -Hinweise einen Konflikt verursachen, ist die sich ergebende Abfrage falsch.Because the SERIALIZABLE and NOLOCK hints conflict, the resulting query is incorrect.

Die PAGLOCK-, NOLOCK-, ROWLOCK-, TABLOCK- oder TABLOCKX -Tabellenhinweise verursachen Konflikte miteinander, genau wie die HOLDLOCK-, NOLOCK-, READCOMMITTED-, REPEATABLEREAD-, SERIALIZABLE -Tabellenhinweise.The PAGLOCK, NOLOCK, ROWLOCK, TABLOCK, or TABLOCKX table hints conflict with each other, as do the HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE table hints.

Hinweise können über die Ebenen geschachtelter Sichten weitergegeben werden.Hints can propagate through levels of nested views. Angenommen, eine Abfrage wendet den HOLDLOCK -Hinweis auf eine v1-Sicht an.For example, suppose a query applies the HOLDLOCK hint on a view v1. Wenn v1 erweitert wird, wird erkennbar, dass die Sicht v2 Teil ihrer Definition ist.When v1 is expanded, we find that view v2 is part of its definition. Die Definition vonv2enthält einen NOLOCK -Hinweis für eine der Basistabellen der Sicht.v2's definition includes a NOLOCK hint on one of its base tables. Diese Tabelle erbt jedoch außerdem den HOLDLOCK -Hinweis für die Sicht v1von der Abfrage.But this table also inherits the HOLDLOCK hint from the query on view v1. Da die NOLOCK - und HOLDLOCK -Hinweise einen Konflikt verursachen, führt die Abfrage zu einem Fehler.Because the NOLOCK and HOLDLOCK hints conflict, the query fails.

Wenn der FORCE ORDER -Hinweis in einer Abfrage verwendet wird, die eine Sicht enthält, wird die Joinreihenfolge der Tabellen innerhalb der Sicht durch die Position der Sicht im sortierten Konstrukt festgelegt.When the FORCE ORDER hint is used in a query that contains a view, the join order of the tables within the view is determined by the position of the view in the ordered construct. Die folgende Abfrage trifft z. B. eine Auswahl aus drei Tabellen und einer Sicht:For example, the following query selects from three tables and a view:

SELECT * FROM Table1, Table2, View1, Table3
WHERE Table1.Col1 = Table2.Col1 
    AND Table2.Col1 = View1.Col1
    AND View1.Col2 = Table3.Col2;
OPTION (FORCE ORDER);

Außerdem ist View1 wie im folgenden Beispiel gezeigt definiert:And View1 is defined as shown in the following:

CREATE VIEW View1 AS
SELECT Colx, Coly FROM TableA, TableB
WHERE TableA.ColZ = TableB.Colz;

Die Joinreihenfolge im Abfrageplan lautet Table1, Table2, TableA, TableB, Table3.The join order in the query plan is Table1, Table2, TableA, TableB, Table3.

Auflösen von Indizes für SichtenResolving Indexes on Views

Wie bei jedem Index entscheidet sich SQL ServerSQL Server nur dann für die Verwendung einer indizierten Sicht in seinem Abfrageplan, wenn der Abfrageoptimierer feststellt, dass dies vorteilhaft ist.As with any index, SQL ServerSQL Server chooses to use an indexed view in its query plan only if the Query Optimizer determines it is beneficial to do so.

Indizierte Sichten können in jeder Edition von SQL ServerSQL Server erstellt werden.Indexed views can be created in any edition of SQL ServerSQL Server. In einigen Editionen einiger Versionen von SQL ServerSQL Server berücksichtigt der Abfrageoptimierer die indizierte Sicht automatisch.In some editions of some versions of SQL ServerSQL Server, the Query Optimizer automatically considers the indexed view. In einigen Editionen einiger Versionen von SQL ServerSQL Server muss der NOEXPAND-Tabellenhinweis verwendet werden, um eine indizierte Sicht zu verwenden.In some editions of some versions of SQL ServerSQL Server, to use an indexed view, the NOEXPAND table hint must be used. Erläuterungen finden Sie in der Dokumentation der Versionen.For clarification, see the documentation for each version.

Der Abfrageoptimierer von SQL ServerSQL Server verwendet eine indizierte Sicht, wenn die folgenden Bedingungen erfüllt sind:The SQL ServerSQL Server Query Optimizer uses an indexed view when the following conditions are met:

  • Die folgenden Sitzungsoptionen sind auf ONfestgelegt:These session options are set to ON:
    • ANSI_NULLS
    • ANSI_PADDING
    • ANSI_WARNINGS
    • ARITHABORT
    • CONCAT_NULL_YIELDS_NULL
    • QUOTED_IDENTIFIER
    • Die NUMERIC_ROUNDABORT -Sitzungsoption ist auf OFF festgelegt.The NUMERIC_ROUNDABORT session option is set to OFF.
  • Der Abfrageoptimierer findet eine Übereinstimmung zwischen den Indexspalten der Sicht und Abfrageelementen, wie z. B.:The Query Optimizer finds a match between the view index columns and elements in the query, such as the following:
    • Suchbedingungsprädikate in der WHERE-KlauselSearch condition predicates in the WHERE clause
    • JoinvorgängeJoin operations
    • AggregatfunktionenAggregate functions
    • GROUP BY -KlauselnClauses
    • TabellenverweiseTable references
  • Die geschätzten Kosten für das Verwenden des Indexes sind die niedrigsten Kosten aller durch den Abfrageoptimierer berücksichtigten Zugriffsmechanismen.The estimated cost for using the index has the lowest cost of any access mechanisms considered by the Query Optimizer.
  • Für jede Tabelle, auf die in der Abfrage verwiesen wird (entweder direkt oder durch Erweitern einer Sicht zum Zugriff auf die zugrunde liegenden Tabellen), die einem Tabellenverweis in der indizierten Sicht entspricht, muss derselbe Satz von Hinweisen in der Abfrage angewendet werden.Every table referenced in the query (either directly, or by expanding a view to access its underlying tables) that corresponds to a table reference in the indexed view must have the same set of hints applied on it in the query.

Hinweis

Die READCOMMITTED - und READCOMMITTEDLOCK -Hinweise werden in diesem Kontext immer als unterschiedliche Hinweise angesehen, unabhängig von der aktuellen Transaktionsisolationsstufe.The READCOMMITTED and READCOMMITTEDLOCK hints are always considered different hints in this context, regardless of the current transaction isolation level.

Abweichend von den Anforderungen für die SET-Optionen und Tabellenhinweise verwendet der Abfrageoptimierer hier dieselben Regeln, mit denen er ermittelt, ob ein Tabellenindex eine Abfrage erfüllt.Other than the requirements for the SET options and table hints, these are the same rules that the Query Optimizer uses to determine whether a table index covers a query. In der zu verwendenden Abfrage für eine indizierte Sicht muss nichts weiter angegeben werden.Nothing else has to be specified in the query for an indexed view to be used.

Eine Abfrage muss nicht explizit in der FROM-Klausel auf eine indizierte Sicht verweisen, damit der Abfrageoptimierer die indizierte Sicht verwendet.A query does not have to explicitly reference an indexed view in the FROM clause for the Query Optimizer to use the indexed view. Falls die Abfrage Verweise auf Spalten in den Basistabellen enthält, die auch in der indizierten Sicht vorhanden sind, und der Abfrageoptimierer schätzt, dass das Verwenden der indizierten Sicht den kostengünstigsten Zugriffsmechanismus darstellt, wählt der Abfrageoptimierer die indizierte Sicht aus. Die Vorgehensweise ist dabei ähnlich wie bei der Auswahl von Basistabellenindizes, wenn in einer Abfrage nicht direkt auf diese verwiesen wird.If the query contains references to columns in the base tables that are also present in the indexed view, and the Query Optimizer estimates that using the indexed view provides the lowest cost access mechanism, the Query Optimizer chooses the indexed view, similar to the way it chooses base table indexes when they are not directly referenced in a query. Der Abfrageoptimierer kann die Sicht auswählen, wenn sie Spalten enthält, auf die die Abfrage nicht verweist, vorausgesetzt die Sicht bietet die kostengünstigste Möglichkeit zum Abdecken einer oder mehrerer Spalten, die in der Abfrage angegeben sind.The Query Optimizer may choose the view when it contains columns that are not referenced by the query, as long as the view offers the lowest cost option for covering one or more of the columns specified in the query.

Der Abfrageoptimierer behandelt eine indizierte Sicht, auf die in der FROM-Klausel verwiesen wird, als Standardsicht.The Query Optimizer treats an indexed view referenced in the FROM clause as a standard view. Der Abfrageoptimierer erweitert am Beginn des Optimierungsprozesses die Definition der Sicht in die Abfrage.The Query Optimizer expands the definition of the view into the query at the start of the optimization process. Dann erfolgt der Abgleich der indizierten Sicht.Then, indexed view matching is performed. Die indizierte Sicht kann im endgültigen Ausführungsplan verwendet werden, der vom Abfrageoptimierer ausgewählt wird, oder stattdessen kann der Plan die erforderlichen Daten aus der Sicht materialisieren, indem auf die Basistabellen zugegriffen wird, auf die durch die Sicht verwiesen wird.The indexed view may be used in the final execution plan selected by the Query Optimizer, or instead, the plan may materialize necessary data from the view by accessing the base tables referenced by the view. Der Abfrageoptimierer wählt die kostengünstigste Alternative aus.The Query Optimizer chooses the lowest-cost alternative.

Verwenden von Hinweisen mit indizierten SichtenUsing Hints with Indexed Views

Sie können verhindern, dass Sichtindizes für eine Abfrage verwendet werden, indem Sie den EXPAND VIEWS -Abfragehinweis verwenden oder indem Sie mit dem NOEXPAND -Tabellenhinweis die Verwendung eines Indexes für eine indizierte Sicht erzwingen, die in der FROM -Klausel einer Abfrage angegeben ist.You can prevent view indexes from being used for a query by using the EXPAND VIEWS query hint, or you can use the NOEXPAND table hint to force the use of an index for an indexed view specified in the FROM clause of a query. Sie sollten jedoch den Abfrageoptimierer für jede Abfrage dynamisch ermitteln lassen, welches die besten Zugriffsmethoden sind.However, you should let the Query Optimizer dynamically determine the best access methods to use for each query. Verwenden Sie EXPAND und NOEXPAND nur in bestimmten Fällen, wenn Tests gezeigt haben, dass durch sie die Leistung deutlich gesteigert wird.Limit your use of EXPAND and NOEXPAND to specific cases where testing has shown that they improve performance significantly.

Die Option EXPAND VIEWS gibt an, dass der Abfrageoptimierer für die gesamte Abfrage keine Sichtindizes verwendet.The EXPAND VIEWS option specifies that the Query Optimizer not use any view indexes for the whole query.

Wenn NOEXPAND für eine Sicht angegeben wird, zieht der Abfrageoptimierer die Verwendung sämtlicher Indizes in Erwägung, die für die Sicht definiert sind.When NOEXPAND is specified for a view, the Query Optimizer considers using any indexes defined on the view. NOEXPAND mit der optionalen INDEX()-Klausel zwingt den Abfrageoptimierer, die angegebenen Indizes zu verwenden.NOEXPAND specified with the optional INDEX() clause forces the Query Optimizer to use the specified indexes. NOEXPAND kann nur für eine indizierte Sicht angegeben werden, nicht für eine nicht indizierte Sicht.NOEXPAND can be specified only for an indexed view and cannot be specified for a view not indexed.

Wenn weder NOEXPAND noch EXPAND VIEWS in einer Abfrage angegeben ist, die eine Sicht enthält, wird die Sicht erweitert, um auf die zugrunde liegenden Tabellen zuzugreifen.When neither NOEXPAND nor EXPAND VIEWS is specified in a query that contains a view, the view is expanded to access underlying tables. Wenn die Abfrage, die die Sicht bildet, irgendwelche Tabellenhinweise enthält, werden diese Hinweise auch an die zugrunde liegenden Tabellen weitergegeben.If the query that makes up the view contains any table hints, these hints are propagated to the underlying tables. (Detaillierte Informationen zu diesem Vorgang finden Sie unter „Sichtauflösung“.) Solange die der Sicht zugrunde liegenden Tabellen identische Sätze von Hinweisen besitzen, kommt die Abfrage für den Abgleich mit einer indizierten Sicht infrage.(This process is explained in more detail in View Resolution.) As long as the set of hints that exists on the underlying tables of the view are identical to each other, the query is eligible to be matched with an indexed view. Zumeist stimmen diese Hinweise miteinander überein, da sie direkt aus der Sicht vererbt werden.Most of the time, these hints will match each other, because they are being inherited directly from the view. Wenn die Abfrage jedoch auf Tabellen und nicht auf Sichten verweist und die direkt auf diese Tabellen angewendeten Hinweise nicht identisch sind, so kommt eine solche Abfrage nicht für den Abgleich mit einer indizierten Sicht infrage.However, if the query references tables instead of views, and the hints applied directly on these tables are not identical, then such a query is not eligible for matching with an indexed view. Wenn die Hinweise INDEX, PAGLOCK, ROWLOCK, TABLOCKX, UPDLOCKoder XLOCK auf die Tabellen angewendet werden, auf die die Abfrage nach der Sichterweiterung verweist, kommt die Abfrage nicht für den Abgleich mit einer indizierten Sicht infrage.If the INDEX, PAGLOCK, ROWLOCK, TABLOCKX, UPDLOCK, or XLOCK hints apply to the tables referenced in the query after view expansion, the query is not eligible for indexed view matching.

Wenn ein Tabellenhinweis in Form von INDEX (index_val[ ,...n] ) auf eine Sicht in einer Abfrage verweist und Sie nicht gleichzeitig den NOEXPAND -Hinweis angeben, wird der Indexhinweis ignoriert.If a table hint in the form of INDEX (index_val[ ,...n] ) references a view in a query and you do not also specify the NOEXPAND hint, the index hint is ignored. Zum Angeben eines bestimmten Indexes verwenden Sie NOEXPAND.To specify use of a particular index, use NOEXPAND.

Allgemein gilt: Wenn der Abfrageoptimierer eine indizierte Sicht mit einer Abfrage abgleicht, werden alle für die Tabellen oder Sichten in der Abfrage angegebenen Hinweise direkt auf die indizierte Sicht angewendet.Generally, when the Query Optimizer matches an indexed view to a query, any hints specified on the tables or views in the query are applied directly to the indexed view. Wenn der Abfrageoptimierer sich entscheidet, keine indizierte Sicht zu verwenden, werden alle Hinweise direkt zu den Tabellen weitergegeben, auf die in der Sicht verwiesen wird.If the Query Optimizer chooses not to use an indexed view, any hints are propagated directly to the tables referenced in the view. Weitere Informationen finden Sie unter „Sichtauflösung“.For more information, see View Resolution. Diese Weitergabe gilt nicht für die Joinhinweise.This propagation does not apply to join hints. Diese werden ausschließlich an ihrer ursprünglichen Position in der Abfrage angewendet.They are applied only in their original position in the query. Joinhinweise werden vom Abfrageoptimierer beim Abgleich von Abfragen zu indizierten Sichten nicht berücksichtigt.Join hints are not considered by the Query Optimizer when matching queries to indexed views. Wenn ein Abfrageplan eine indizierte Sicht verwendet, die mit einem Teil einer Abfrage übereinstimmt, der einen Joinhinweis enthält, wird der Joinhinweis im Plan nicht verwendet.If a query plan uses an indexed view that matches part of a query that contains a join hint, the join hint is not used in the plan.

In den Definitionen von indizierten Sichten sind Hinweise nicht zulässig.Hints are not allowed in the definitions of indexed views. In den Kompatibilitätsmodi 80 und höher ignoriert SQL ServerSQL Server die in den Definitionen indizierter Sichten enthaltenen Hinweise, wenn diese verwaltet werden oder wenn Abfragen ausgeführt werden, in denen indizierte Sichten verwendet werden.In compatibility mode 80 and higher, SQL ServerSQL Server ignores hints inside indexed view definitions when maintaining them, or when executing queries that use indexed views. Obwohl die Verwendung von Hinweisen in den Definitionen indizierter Sichten im Kompatibilitätsmodus 80 nicht zu einem Syntaxfehler führt, werden sie ignoriert.Although using hints in indexed view definitions will not produce a syntax error in 80 compatibility mode, they are ignored.

Auflösen verteilter partitionierter SichtenResolving Distributed Partitioned Views

Der SQL ServerSQL Server-Abfrageprozessor optimiert die Leistung von verteilten partitionierten Sichten.The SQL ServerSQL Server query processor optimizes the performance of distributed partitioned views. Der wichtigste Aspekt bei der Leistung von verteilten partitionierten Sichten ist das Minimieren der Datenmenge, die zwischen den Mitgliedsservern übertragen wird.The most important aspect of distributed partitioned view performance is minimizing the amount of data transferred between member servers.

SQL ServerSQL Server erstellt intelligente, dynamische Pläne, in denen verteilte Abfragen effizient für den Zugriff auf Daten in Remotemitgliedstabellen verwendet werden:builds intelligent, dynamic plans that make efficient use of distributed queries to access data from remote member tables:

  • Zunächst verwendet der Abfrageprozessor OLE DB, um die Definitionen der CHECK-Einschränkungen aus jeder Mitgliedstabelle abzurufen.The Query Processor first uses OLE DB to retrieve the check constraint definitions from each member table. Dadurch kann der Abfrageprozessor die Verteilung der Schlüsselwerte auf die Mitgliedstabellen zuordnen.This allows the query processor to map the distribution of key values across the member tables.
  • Der Abfrageprozessor vergleicht die Schlüsselbereiche, die in der WHERE-Klausel einer Transact-SQLTransact-SQL-Anweisung angegeben sind, mit der Zuordnung, die die Verteilung der Zeilen in den Mitgliedstabellen anzeigt.The Query Processor compares the key ranges specified in an Transact-SQLTransact-SQL statement WHERE clause to the map that shows how the rows are distributed in the member tables. Anschließend erstellt der Abfrageprozessor einen Abfrageausführungsplan, der mithilfe von verteilten Abfragen nur die Remotezeilen abruft, die zum Ausführen der Transact-SQLTransact-SQL-Anweisung erforderlich sind.The query processor then builds a query execution plan that uses distributed queries to retrieve only those remote rows that are required to complete the Transact-SQLTransact-SQL statement. Darüber hinaus wird der Ausführungsplan so erstellt, dass alle Zugriffe auf Remotemitgliedstabellen, entweder für Daten oder Metadaten, so lange verzögert werden, bis die Informationen benötigt werden.The execution plan is also built in such a way that any access to remote member tables, for either data or metadata, are delayed until the information is required.

Stellen Sie sich z.B. ein System vor, in dem eine Kundentabelle über Server1 (CustomerID von 1 bis 3299999), Server2 (CustomerID von 3300000 bis 6599999) und Server3 (CustomerID von 6600000 bis 9999999) partitioniert ist.For example, consider a system where a customers table is partitioned across Server1 (CustomerID from 1 through 3299999), Server2 (CustomerID from 3300000 through 6599999), and Server3 (CustomerID from 6600000 through 9999999).

Stellen Sie sich den Ausführungsplan vor, der für diese auf Server1 ausgeführte Abfrage erstellt wird:Consider the execution plan built for this query executed on Server1:

SELECT *
FROM CompanyData.dbo.Customers
WHERE CustomerID BETWEEN 3200000 AND 3400000;

Der Ausführungsplan für diese Abfrage extrahiert die Zeilen mit CustomerID -Schlüsselwerten von 3200000 bis 3299999 aus der lokalen Mitgliedstabelle und gibt eine verteilte Abfrage aus, um die Zeilen mit Schlüsselwerten von 3300000 bis 3400000 von Server2 abzurufen.The execution plan for this query extracts the rows with CustomerID key values from 3200000 through 3299999 from the local member table, and issues a distributed query to retrieve the rows with key values from 3300000 through 3400000 from Server2.

Der Abfrageprozessor von SQL ServerSQL Server kann zudem eine dynamische Logik in die Abfrageausführungspläne für Transact-SQLTransact-SQL-Anweisungen integrieren, bei denen die Schlüsselwerte nicht bekannt sind, wenn der Plan erstellt werden muss.The SQL ServerSQL Server Query Processor can also build dynamic logic into query execution plans for Transact-SQLTransact-SQL statements in which the key values are not known when the plan must be built. Sehen Sie sich z.B. diese gespeicherte Prozedur an:For example, consider this stored procedure:

CREATE PROCEDURE GetCustomer @CustomerIDParameter INT
AS
SELECT *
FROM CompanyData.dbo.Customers
WHERE CustomerID = @CustomerIDParameter;

SQL ServerSQL Server kann nicht vorhersagen, welcher Schlüsselwert jeweils bei der Ausführung der Prozedur durch den @CustomerIDParameter-Parameter zurückgegeben wird.cannot predict what key value will be supplied by the @CustomerIDParameter parameter every time the procedure is executed. Da der Schlüsselwert nicht vorhergesagt werden kann, kann der Abfrageprozessor auch nicht vorhersagen, auf welche Mitgliedstabelle zugegriffen werden muss.Because the key value cannot be predicted, the query processor also cannot predict which member table will have to be accessed. Wegen dieses Aspekts erstellt SQL ServerSQL Server einen Ausführungsplan mit Bedingungslogik (so genannte dynamische Filter), um zu steuern, auf welche Mitgliedstabelle basierend auf den Eingabeparameterwerten zugegriffen wird.To handle this case, SQL ServerSQL Server builds an execution plan that has conditional logic, referred to as dynamic filters, to control which member table is accessed, based on the input parameter value. Angenommen die gespeicherte Prozedur GetCustomer wurde für Server1 ausgeführt, dann kann die Logik des Ausführungsplans wie folgt dargestellt werden:Assuming the GetCustomer stored procedure was executed on Server1, the execution plan logic can be represented as shown in the following:

IF @CustomerIDParameter BETWEEN 1 and 3299999
   Retrieve row from local table CustomerData.dbo.Customer_33
ELSE IF @CustomerIDParameter BETWEEN 3300000 and 6599999
   Retrieve row from linked table Server2.CustomerData.dbo.Customer_66
ELSE IF @CustomerIDParameter BETWEEN 6600000 and 9999999
   Retrieve row from linked table Server3.CustomerData.dbo.Customer_99

SQL ServerSQL Server erstellt diese dynamischen Ausführungspläne manchmal sogar für nicht parametrisierte Abfragen.sometimes builds these types of dynamic execution plans even for queries that are not parameterized. Der Abfrageoptimierer kann eine Abfrage parametrisieren, sodass der Ausführungsplan wieder verwendet werden kann.The Query Optimizer may parameterize a query so that the execution plan can be reused. Falls der Abfrageoptimierer eine Abfrage parametrisiert, die auf eine partitionierte Sicht verweist, kann der Abfrageoptimierer nicht mehr davon ausgehen, dass die erforderlichen Zeilen aus einer bestimmten Basistabelle stammen.If the Query Optimizer parameterizes a query referencing a partitioned view, the Query Optimizer can no longer assume the required rows will come from a specified base table. In diesem Fall muss der Optimierer dynamische Filter im Ausführungsplan verwenden.It will then have to use dynamic filters in the execution plan.

Ausführung von gespeicherten Prozeduren und TriggernStored Procedure and Trigger Execution

SQL ServerSQL Server speichert nur die Quelle für gespeicherte Prozeduren und Trigger.stores only the source for stored procedures and triggers. Wenn eine gespeicherte Prozedur oder ein Trigger das erste Mal ausgeführt wird, wird die Quelle zu einem Ausführungsplan kompiliert.When a stored procedure or trigger is first executed, the source is compiled into an execution plan. Wenn die gespeicherte Prozedur oder der Trigger erneut ausgeführt wird, bevor der Ausführungsplan aus dem Arbeitsspeicher entfernt wurde, erkennt die relationale Engine den vorhandenen Plan und verwendet ihn erneut.If the stored procedure or trigger is again executed before the execution plan is aged from memory, the relational engine detects the existing plan and reuses it. Wenn der Plan aus dem Arbeitsspeicher entfernt wurde, wird ein neuer Plan erstellt.If the plan has aged out of memory, a new plan is built. Dieser Vorgang ist mit dem Verfahren vergleichbar, das SQL ServerSQL Server für alle Transact-SQLTransact-SQL-Anweisungen anwendet.This process is similar to the process SQL ServerSQL Server follows for all Transact-SQLTransact-SQL statements. Der wesentliche Leistungsvorteil, den gespeicherte Prozeduren und Trigger in SQL ServerSQL Server im Vergleich zu Batches dynamischer Transact-SQLTransact-SQL besitzen, besteht darin, dass ihre Transact-SQLTransact-SQL-Anweisungen immer identisch sind.The main performance advantage that stored procedures and triggers have in SQL ServerSQL Server compared with batches of dynamic Transact-SQLTransact-SQL is that their Transact-SQLTransact-SQL statements are always the same. Aus diesem Grund können sie durch die relationale Engine auf einfache Weise vorhandenen Ausführungsplänen zugeordnet werden.Therefore, the relational engine easily matches them with any existing execution plans. Pläne für gespeicherte Prozeduren und Trigger können einfach erneut verwendet werden.Stored procedure and trigger plans are easily reused.

Der Ausführungsplan für gespeicherte Prozeduren und Trigger wird getrennt von dem Ausführungsplan für den Batch ausgeführt, der die gespeicherte Prozedur aufruft oder den Trigger auslöst.The execution plan for stored procedures and triggers is executed separately from the execution plan for the batch calling the stored procedure or firing the trigger. Dadurch können die Ausführungspläne für gespeicherte Prozeduren und Trigger mehrmals erneut verwendet werden.This allows for greater reuse of the stored procedure and trigger execution plans.

Zwischenspeichern und Wiederverwenden von AusführungsplänenExecution Plan Caching and Reuse

SQL ServerSQL Server verfügt über einen Arbeitsspeicherpool, der zum Speichern von Ausführungsplänen und von Datenpuffern verwendet wird.has a pool of memory that is used to store both execution plans and data buffers. Der Prozentsatz des Pools, der entweder für Ausführungspläne oder für Datenpuffer zugeordnet wird, verändert sich dynamisch in Abhängigkeit vom Status des Systems.The percentage of the pool allocated to either execution plans or data buffers fluctuates dynamically, depending on the state of the system. Der Teil des Arbeitsspeicherpools, der zum Speichern von Ausführungsplänen verwendet wird, wird Plancache genannt.The part of the memory pool that is used to store execution plans is referred to as the plan cache.

SQL ServerSQL Server-Ausführungspläne weisen die folgenden Hauptkomponenten auf:execution plans have the following main components:

  • Abfrageausführungsplan Query Execution Plan
    Bei dem größten Teil des Ausführungsplans handelt es sich um eine eintrittsinvariante, schreibgeschützte Datenstruktur, die von einer beliebigen Anzahl von Benutzern verwendet werden kann.The bulk of the execution plan is a re-entrant, read-only data structure used by any number of users. Man bezeichnet diesen Teil als Abfrageplan.This is referred to as the query plan. Im Abfrageplan wird kein Benutzerkontext gespeichert.No user context is stored in the query plan. Im Arbeitsspeicher befinden sich immer nur eine oder zwei Kopien des Abfrageplans: eine Kopie für alle seriellen Ausführungen und eine weitere für alle parallelen Ausführungen.There are never more than one or two copies of the query plan in memory: one copy for all serial executions and another for all parallel executions. Die parallele Kopie deckt alle parallelen Ausführungen ab, und zwar unabhängig von ihrem Grad an Parallelität.The parallel copy covers all parallel executions, regardless of their degree of parallelism.

  • Ausführungskontext

    Execution context
    Jeder Benutzer, der die Abfrage zurzeit ausführt, verfügt über eine Datenstruktur mit den Daten, die für diese Ausführung spezifisch sind, z. B. Parameterwerte.Each user that is currently executing the query has a data structure that holds the data specific to their execution, such as parameter values. Diese Datenstruktur wird als Ausführungskontext bezeichnet.This data structure is referred to as the execution context. Die Datenstrukturen des Ausführungskontexts werden wiederverwendet.The execution context data structures are reused. Wenn ein Benutzer eine Abfrage ausführt und eine der Strukturen nicht verwendet wird, wird diese Struktur erneut initialisiert, und zwar diesmal mit dem Kontext für den neuen Benutzer.If a user executes a query and one of the structures is not being used, it is reinitialized with the context for the new user.

execution_context

Wenn eine Transact-SQLTransact-SQL-Anweisung in SQL ServerSQL Server ausgeführt wird, durchsucht die relationale Engine zunächst den Plancache, um zu überprüfen, ob ein vorhandener Ausführungsplan für dieselbe Transact-SQLTransact-SQL-Anweisung vorhanden ist.When any Transact-SQLTransact-SQL statement is executed in SQL ServerSQL Server, the Relational Engine first looks through the plan cache to verify that an existing execution plan for the same Transact-SQLTransact-SQL statement exists. Die Transact-SQLTransact-SQL-Anweisung wird dann als vorhanden qualifiziert, wenn sie mit einer zuvor ausgeführten Transact-SQLTransact-SQL-­Anweisung mit einem zwischengespeicherten Plan Zeichen für Zeichen übereinstimmt.The Transact-SQLTransact-SQL statement qualifies as existing if it literally matches a previously executed Transact-SQLTransact-SQL statement with a cached plan, character per character. SQL ServerSQL Server verwendet sämtliche vorhandenen Pläne wieder, die hierbei gefunden werden, und spart sich somit den Aufwand für das erneute Kompilieren der Transact-SQLTransact-SQL-Anweisung.reuses any existing plan it finds, saving the overhead of recompiling the Transact-SQLTransact-SQL statement. Wenn kein Ausführungsplan vorhanden ist, generiert SQL ServerSQL Server einen neuen Ausführungsplan für die Abfrage.If no existing execution plan exists, SQL ServerSQL Server generates a new execution plan for the query.

Hinweis

Einige Transact-SQLTransact-SQL -Anweisungen werden nicht zwischengespeichert. Beispiele hierfür sind Anweisungen für Massenvorgänge, die auf Zeilenspeicher ausgeführt werden, oder Anweisungen mit Zeichenfolgenliteralen, die größer als 8 KB sind.Some Transact-SQLTransact-SQL statements are not cached, such as bulk operation statements running on rowstore or statements containing string literals larger than 8 KB in size.

SQL ServerSQL Server verwendet einen effizienten Algorithmus, um vorhandene Ausführungspläne für bestimmte Transact-SQLTransact-SQL-Anweisungen zu suchen.has an efficient algorithm to find any existing execution plans for any specific Transact-SQLTransact-SQL statement. In den meisten Systemen können durch das erneute Verwenden vorhandener Pläne anstelle des erneuten Kompilierens jeder Transact-SQLTransact-SQL-Anweisung mehr Ressourcen eingespart werden, als für den Scan nach vorhandenen Plänen benötigt werden.In most systems, the minimal resources that are used by this scan are less than the resources that are saved by being able to reuse existing plans instead of compiling every Transact-SQLTransact-SQL statement.

Die Algorithmen, die Transact-SQLTransact-SQL-Anweisungen mit vorhandenen, nicht verwendeten Ausführungsplänen im Cache vergleichen, erfordern, dass alle Objektverweise vollqualifiziert sind.The algorithms to match new Transact-SQLTransact-SQL statements to existing, unused execution plans in the cache require that all object references be fully qualified. Angenommen, Person ist das Standardschema für den Benutzer, der die unten angegebenen SELECT-Anweisungen ausführt.For example, assume that Person is the default schema for the user executing the below SELECT statements. Da es in diesem Beispiel nicht erforderlich ist, dass die Tabelle Person zum Ausführen vollqualifiziert ist, bedeutet dies, dass die zweite Anweisung nicht mit einem vorhandenen Plan verglichen wird, aber die dritte Anweisung:While in this example it is not required that the Person table is fully qualified to execute, it means that the second statement is not matched with an existing plan, but the third is matched:

SELECT * FROM Person;
GO
SELECT * FROM Person.Person;
GO
SELECT * FROM Person.Person;
GO

Entfernen von Ausführungsplänen aus dem PlancacheRemoving Execution Plans from the Plan Cache

Ausführungspläne verbleiben im Plancache, solange ausreichend Speicherplatz für deren Speicherung zur Verfügung steht.Execution plans remain in the plan cache as long as there is enough memory to store them. Wenn nicht ausreichend Speicherplatz zur Verfügung steht, ermittelt SQL Server-Datenbank-EngineSQL Server Database Engine kostenbasiert, welche Ausführungspläne aus dem Plancache entfernt werden.When memory pressure exists, the SQL Server-Datenbank-EngineSQL Server Database Engine uses a cost-based approach to determine which execution plans to remove from the plan cache. Für die kostenbasierte Entscheidung erhöht und senkt SQL Server-Datenbank-EngineSQL Server Database Engine die aktuelle Kostenvariable für sämtliche Ausführungspläne anhand der im Folgenden aufgeführten Faktoren.To make a cost-based decision, the SQL Server-Datenbank-EngineSQL Server Database Engine increases and decreases a current cost variable for each execution plan according to the following factors.

Wenn ein Benutzerprozess einen Ausführungsplan in den Cache einfügt, werden die aktuellen Kosten auf die Kosten der ursprünglichen Abfragekompilierung festgelegt. Für Ad-hoc-Ausführungspläne legt der Benutzerprozess die aktuellen Kosten auf 0 (null) fest.When a user process inserts an execution plan into the cache, the user process sets the current cost equal to the original query compile cost; for ad-hoc execution plans, the user process sets the current cost to zero. Jedes Mal, wenn danach ein Benutzerprozess auf einen Ausführungsplan verweist, werden die aktuellen Kosten auf die ursprünglich kompilierten Kosten zurückgesetzt. Für Ad-hoc-Ausführungspläne erhöht der Benutzerprozess die aktuellen Kosten.Thereafter, each time a user process references an execution plan, it resets the current cost to the original compile cost; for ad-hoc execution plans the user process increases the current cost. Für alle Pläne entspricht der maximale Wert für die aktuellen Kosten den Kosten der ursprünglichen Kompilierung.For all plans, the maximum value for the current cost is the original compile cost.

Wenn nicht ausreichend Speicherplatz zur Verfügung steht, werden von SQL Server-Datenbank-EngineSQL Server Database Engine Ausführungspläne aus dem Plancache gelöscht.When memory pressure exists, the SQL Server-Datenbank-EngineSQL Server Database Engine responds by removing execution plans from the plan cache. Um zu ermitteln, welche Pläne entfernt werden sollen, überprüft SQL Server-Datenbank-EngineSQL Server Database Engine wiederholt den Status sämtlicher Ausführungspläne. Die Pläne, deren aktuelle Kosten 0 (null) betragen, werden entfernt.To determine which plans to remove, the SQL Server-Datenbank-EngineSQL Server Database Engine repeatedly examines the state of each execution plan and removes plans when their current cost is zero. Ein Ausführungsplan, dessen aktuelle Kosten 0 (null) betragen, wird bei unzureichendem Speicher nicht automatisch entfernt. Der Ausführungsplan wird nur bei einer Überprüfung durch SQL Server-Datenbank-EngineSQL Server Database Engine entfernt, wenn die aktuellen Kosten 0 (null) betragen.An execution plan with zero current cost is not removed automatically when memory pressure exists; it is removed only when the SQL Server-Datenbank-EngineSQL Server Database Engine examines the plan and the current cost is zero. Wird ein Ausführungsplan derzeit nicht von einer Abfrage verwendet, werden bei der Überprüfung des Plans die aktuellen Kosten von SQL Server-Datenbank-EngineSQL Server Database Engine durch Reduzieren dieser Kosten gegen 0 (null) gesenkt.When examining an execution plan, the SQL Server-Datenbank-EngineSQL Server Database Engine pushes the current cost towards zero by decreasing the current cost if a query is not currently using the plan.

SQL Server-Datenbank-EngineSQL Server Database Engine überprüft die Ausführungspläne wiederholt, bis genügend Ausführungspläne entfernt wurden, um die Speicheranforderungen zu erfüllen.The SQL Server-Datenbank-EngineSQL Server Database Engine repeatedly examines the execution plans until enough have been removed to satisfy memory requirements. Wenn nicht ausreichend Speicher zur Verfügung steht, können die Kosten eines Ausführungsplans mehrmals erhöht und gesenkt werden.While memory pressure exists, an execution plan may have its cost increased and decreased more than once. Sobald wieder ausreichend Speicher zur Verfügung steht, werden die aktuellen Kosten nicht verwendeter Ausführungspläne von SQL Server-Datenbank-EngineSQL Server Database Engine nicht mehr gesenkt. Alle Ausführungspläne verbleiben im Plancache, auch wenn die Kosten 0 (null) betragen.When memory pressure no longer exists, the SQL Server-Datenbank-EngineSQL Server Database Engine stops decreasing the current cost of unused execution plans and all execution plans remain in the plan cache, even if their cost is zero.

Wenn nicht ausreichend Speicher zur Verfügung steht, verwendet SQL Server-Datenbank-EngineSQL Server Database Engine den Ressourcenmonitor und Benutzerarbeitsthreads, um Speicherplatz im Prozedurcache freizugeben.The SQL Server-Datenbank-EngineSQL Server Database Engine uses the resource monitor and user worker threads to free memory from the plan cache in response to memory pressure. Vom Ressourcenmonitor und von den Benutzerarbeitsthreads können gleichzeitig ausgeführte Pläne überprüft werden, um die Kosten für die nicht verwendeten Ausführungspläne zu senken.The resource monitor and user worker threads can examine plans run concurrently to decrease the current cost for each unused execution plan. Wenn nicht ausreichend globaler Speicher zur Verfügung steht, werden durch den Ressourcenmonitor Ausführungspläne aus dem Plancache gelöscht.The resource monitor removes execution plans from the plan cache when global memory pressure exists. Dadurch wird die Einhaltung von Richtlinien für den Systemspeicher, Prozessspeicher, Ressourcenpoolspeicher und die maximale Größe aller Caches erzwungen.It frees memory to enforce policies for system memory, process memory, resource pool memory, and maximum size for all caches.

Die maximale Größe für alle Caches ist eine Funktion der Pufferpoolgröße und kann den maximalen Serverarbeitsspeicher nicht überschreiten.The maximum size for all caches is a function of the buffer pool size and cannot exceed the maximum server memory. Weitere Informationen zum Konfigurieren des maximalen Serverarbeitsspeichers finden Sie in den Details zur Einstellung max server memory von sp_configure.For more information on configuring the maximum server memory, see the max server memory setting in sp_configure.

Wenn nicht ausreichend Einzelcachespeicher zur Verfügung steht, werden durch die Benutzerarbeitsthreads Ausführungspläne aus dem Plancache gelöscht.The user worker threads remove execution plans from the plan cache when single cache memory pressure exists. Dadurch wird die Einhaltung der Richtlinien für die maximale Einzelcachegröße und die maximale Anzahl von Einzelcacheeinträgen erzwungen.They enforce policies for maximum single cache size and maximum single cache entries.

In den folgenden Beispielen wird erläutert, welche Ausführungspläne aus dem Plancache entfernt werden:The following examples illustrate which execution plans get removed from the plan cache:

  • Auf einen Ausführungsplan wird regelmäßig verwiesen, sodass seine Kosten nie den Wert 0 (null) erreichen.An execution plan is frequently referenced so that its cost never goes to zero. Der Plan verbleibt im Plancache und wird nur dann entfernt, wenn nicht genügend Arbeitsspeicher vorhanden ist und die aktuellen Kosten 0 (null) sind.The plan remains in the plan cache and is not removed unless there is memory pressure and the current cost is zero.
  • Ein Ad-hoc-Ausführungsplan wird eingefügt. Auf diesen wird erst wieder verwiesen, wenn nicht ausreichend Speicherplatz zur Verfügung steht.An ad-hoc execution plan is inserted and is not referenced again before memory pressure exists. Ad-hoc-Pläne werden mit einem Wert für die aktuellen Kosten von 0 (null) initialisiert. Daher wird der Plan aus dem Plancache entfernt, wenn der Ausführungsplan vom SQL Server-Datenbank-EngineSQL Server Database Engine überprüft wird und die aktuellen Kosten 0 (null) betragen.Since ad-hoc plans are initialized with a current cost of zero, when the SQL Server-Datenbank-EngineSQL Server Database Engine examines the execution plan, it will see the zero current cost and remove the plan from the plan cache. Der Ad-hoc-Ausführungsplan verbleibt im Plancache mit aktuellen Kosten vom Wert 0 (null), wenn genügend Arbeitsspeicher vorhanden ist.The ad-hoc execution plan remains in the plan cache with a zero current cost when memory pressure does not exist.

Um einen einzelnen Plan oder alle Pläne manuell aus dem Cache zu entfernen, verwenden Sie DBCC FREEPROCCACHE.To manually remove a single plan or all plans from the cache, use DBCC FREEPROCCACHE. Ab SQL Server 2016 (13.x)SQL Server 2016 (13.x) ist ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE verfügbar, um den Prozedur-/Plancache für die Datenbank im Bereich zu löschen.Starting with SQL Server 2016 (13.x)SQL Server 2016 (13.x), the ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE to clear the procedure (plan) cache for the database in scope.

Erneutes Kompilieren von AusführungsplänenRecompiling Execution Plans

Bestimmte Änderungen in einer Datenbank können dazu führen, dass ein Ausführungsplan basierend auf dem neuen Status der Datenbank ineffizient oder ungültig ist.Certain changes in a database can cause an execution plan to be either inefficient or invalid, based on the new state of the database. SQL ServerSQL Server erkennt die Änderungen, die einen Ausführungsplan ungültig machen, und kennzeichnet den Plan als ungültig.detects the changes that invalidate an execution plan and marks the plan as not valid. Für die nächste Verbindung, die die Abfrage ausführt, muss dann ein neuer Plan kompiliert werden.A new plan must then be recompiled for the next connection that executes the query. Folgende Bedingungen können dazu führen, dass ein Plan ungültig wird:The conditions that invalidate a plan include the following:

  • Änderungen, die an einer Tabelle oder einer Sicht vorgenommen werden, auf die in der Abfrage verwiesen wird (ALTER TABLE und ALTER VIEW).Changes made to a table or view referenced by the query (ALTER TABLE and ALTER VIEW).
  • Änderungen, die an einer einzigen Prozedur vorgenommen werden, durch die alle Pläne für die Prozedur aus dem Cache gelöscht werden (ALTER PROCEDURE).Changes made to a single procedure, which would drop all plans for that procedure from the cache (ALTER PROCEDURE).
  • Änderungen an Indizes, die vom Ausführungsplan verwendet werden.Changes to any indexes used by the execution plan.
  • Updates der vom Ausführungsplan verwendeten Statistiken, die entweder explizit durch eine Anweisung, wie beispielsweise UPDATE STATISTICS, oder automatisch generiert werden.Updates on statistics used by the execution plan, generated either explicitly from a statement, such as UPDATE STATISTICS, or generated automatically.
  • Löschen eines Indexes, der von dem Ausführungsplan verwendet wird.Dropping an index used by the execution plan.
  • Ein expliziter Aufruf von sp_recompile.An explicit call to sp_recompile.
  • Eine große Anzahl von Änderungen an Schlüsseln (generiert durch INSERT - oder DELETE -Anweisungen von anderen Benutzern, die eine Tabelle ändern, auf die in der Abfrage verwiesen wird).Large numbers of changes to keys (generated by INSERT or DELETE statements from other users that modify a table referenced by the query).
  • Bei Tabellen mit Triggern eine deutliche Erhöhung der Zeilenanzahl in der eingefügten oder gelöschten Tabelle.For tables with triggers, if the number of rows in the inserted or deleted tables grows significantly.
  • Ausführen einer gespeicherten Prozedur mithilfe der Option WITH RECOMPILE .Executing a stored procedure using the WITH RECOMPILE option.

Die meisten Neukompilierungen sind erforderlich, um die Richtigkeit der Anweisungen sicherzustellen oder um möglicherweise schnellere Abfrageausführungspläne zu erhalten.Most recompilations are required either for statement correctness or to obtain potentially faster query execution plans.

Jedes Mal, wenn in früheren SQL ServerSQL Server-Versionen als 2005 eine in einem Batch vorhandene Anweisung eine Neukompilierung ausgelöst hat, wurde der gesamte durch eine gespeicherte Prozedur, einen Trigger, einen Ad-hoc-Batch oder eine vorbereitete Anweisung übermittelte Batch noch mal kompiliert.In SQL ServerSQL Server 2000, whenever a statement within a batch causes recompilation, the whole batch, whether submitted through a stored procedure, trigger, ad-hoc batch, or prepared statement, is recompiled. Ab SQL Server 2005 (9.x)SQL Server 2005 (9.x) wird nur die Anweisung innerhalb des Batches, der die Neukompilierung auslöst, noch mal kompiliert.Starting with SQL Server 2005 (9.x)SQL Server 2005 (9.x), only the statement inside the batch that causes recompilation is recompiled. Zudem gibt es in SQL Server 2005 (9.x)SQL Server 2005 (9.x) und höheren Versionen aufgrund der erweiterten Features zusätzliche Neukompilierungstypen.Also, there are more types of recompilations in SQL Server 2005 (9.x)SQL Server 2005 (9.x) and later because of its expanded feature set.

Die Neukompilierung auf Anweisungsebene wirkt sich positiv auf die Leistung aus, da in den meisten Fällen wenige Anweisungen Neukompilierungen und die damit verbundenen Sanktionen in Bezug auf die CPU-Zeit und die Sperren verursachen.Statement-level recompilation benefits performance because, in most cases, a small number of statements causes recompilations and their associated penalties, in terms of CPU time and locks. Diese Sanktionen werden daher für die anderen Anweisungen innerhalb des Batchs vermieden, für die keine Neukompilierung erforderlich ist.These penalties are therefore avoided for the other statements in the batch that do not have to be recompiled.

Das erweiterte sql_statement_recompile-Ereignis (xEvent) meldet Neukompilierungen auf Anweisungsebene.The sql_statement_recompile extended event (xEvent) reports statement-level recompilations. Dieses xEvent erscheint, wenn ein beliebiger Batch eine Neukompilierung auf Anweisungsebene erfordert.This xEvent occurs when a statement-level recompilation is required by any kind of batch. Dazu gehören gespeicherte Prozeduren, Trigger, Ad-hoc-Batches und Abfragen.This includes stored procedures, triggers, ad hoc batches and queries. Batches können möglicherweise über mehrere Schnittstellen, einschließlich sp_executesql, dynamische SQL-Anweisungen, Prepare-Methoden oder Execute-Methoden gesendet werden.Batches may be submitted through several interfaces, including sp_executesql, dynamic SQL, Prepare methods or Execute methods. Die recompile_cause-Spalte von sql_statement_recompile xEvent enthält einen ganzzahligen Code, der den Grund für die Neukompilierung angibt.The recompile_cause column of sql_statement_recompile xEvent contains an integer code that indicates the reason for the recompilation. Die folgende Tabelle enthält die möglichen Gründe:The following table contains the possible reasons:

Schema geändertSchema changed Statistiken geändertStatistics changed
Verzögerte KompilierungDeferred compile SET-Option geändertSET option changed
Temporäre Tabelle geändertTemporary table changed Remote-Rowset geändertRemote rowset changed
FOR BROWSE-Berechtigung geändertFOR BROWSE permission changed Abfragebenachrichtigungsumgebung geändertQuery notification environment changed
Partitionierte Sicht geändertPartitioned view changed Cursoroptionen geändertCursor options changed
OPTION (RECOMPILE) angefordert.Requested Parametrisierter Plan geleertParameterized plan flushed
Plan geändert, der die Datenbankversion betrifftPlan affecting database version changed Erzwingende Richtlinie des Abfragespeicherplans geändertQuery Store plan forcing policy changed
Erzwingende Richtlinie des Abfragespeicherplans fehlgeschlagenQuery Store plan forcing failed Plan des Abfragespeichers fehltQuery Store missing the plan

Hinweis

In SQL ServerSQL Server-Versionen, in denen xEvents nicht verfügbar sind, kann die SP:Recompile-Ablaufverfolgung des SQL ServerSQL Server-Profiler auch zur Berichterstellung von Neukompilierungen auf Anweisungsebene verwendet werden.In SQL ServerSQL Server versions where xEvents are not available, then the SQL ServerSQL Server Profiler SP:Recompile trace event can be used for the same purpose of reporting statement-level recompilations. Das Ablaufereignis SQL:StmtRecompile meldet ebenfalls Neukompilierungen, und dieses Ablaufereignis kann auch zum Nachverfolgen und Debuggen von Neukompilierungen verwendet werden.The trace event SQL:StmtRecompile also reports statement-level recompilations, and this trace event can also be used to track and debug recompilations. Während „SP:Recompile“ nur für gespeicherte Prozeduren und Trigger generiert wird, wird SQL:StmtRecompile für gespeicherte Prozeduren, Trigger, Ad-hoc-Batches, Batches, die mithilfe von sp_executesql ausgeführt werden, vorbereitete Abfragen sowie für dynamisches SQL generiert.Whereas SP:Recompile generates only for stored procedures and triggers, SQL:StmtRecompile generates for stored procedures, triggers, ad-hoc batches, batches that are executed by using sp_executesql, prepared queries, and dynamic SQL. Die EventSubClass-Spalte von SP:Recompile und SQL:StmtRecompile enthält einen ganzzahligen Code, der den Grund für die Neukompilierung angibt.The EventSubClass column of SP:Recompile and SQL:StmtRecompile contains an integer code that indicates the reason for the recompilation. Die Codes sind hier beschrieben.The codes are described here.

Hinweis

Wenn die Datenbankoption AUTO_UPDATE_STATISTICS auf ON festgelegt wird, werden Abfragen neu kompiliert, wenn sie Tabellen oder indizierte Sichten betreffen, deren Statistiken aktualisiert wurden oder deren Kardinalitäten sich seit der letzten Ausführung signifikant geändert haben.When the AUTO_UPDATE_STATISTICS database option is set to ON, queries are recompiled when they target tables or indexed views whose statistics have been updated or whose cardinalities have changed significantly since the last execution. Dieses Verhalten gilt für standardmäßige benutzerdefinierte Tabellen, temporäre Tabellen und die durch DML-Trigger erstellten eingefügten und gelöschten Tabellen.This behavior applies to standard user-defined tables, temporary tables, and the inserted and deleted tables created by DML triggers. Wenn sich sehr viele Neukompilierungen auf die Abfrageleistung auswirken, können Sie diese Einstellung in OFFändern.If query performance is affected by excessive recompilations, consider changing this setting to OFF. Wenn die AUTO_UPDATE_STATISTICS-Datenbankoption auf OFF festgelegt wird, werden auf der Grundlage von Statistiken oder wegen Änderungen der Kardinalität keine Neukompilierungen durchgeführt, mit Ausnahme der durch DML INSTEAD OF-Trigger erstellten eingefügten und gelöschten Tabellen.When the AUTO_UPDATE_STATISTICS database option is set to OFF, no recompilations occur based on statistics or cardinality changes, with the exception of the inserted and deleted tables that are created by DML INSTEAD OF triggers. Da diese Tabellen in „tempdb“ erstellt wurden, hängt die Neukompilierung von Abfragen, die auf diese Tabellen zugreifen, von der AUTO_UPDATE_STATISTICS -Einstellung in „tempdb“ ab.Because these tables are created in tempdb, the recompilation of queries that access them depends on the setting of AUTO_UPDATE_STATISTICS in tempdb. Beachten Sie, dass, auch wenn diese Einstellung auf OFF festgelegt ist, Abfragen in früheren SQL ServerSQL Server-Versionen als 2005 weiterhin auf der Grundlage der Kardinalitätsänderungen in den durch DML-Trigger eingefügten und gelöschten Tabellen noch mal kompiliert werden.Note that in SQL ServerSQL Server 2000, queries continue to recompile based on cardinality changes to the DML trigger inserted and deleted tables, even when this setting is OFF.

Parameter und Wiederverwendung von Ausführungsplänen

Parameters and Execution Plan Reuse

Durch die Verwendung von Parametern, einschließlich der Parametermarkierungen in ADO-, OLE DB- und ODBC-Anwendungen, kann die Wiederverwendbarkeit von Ausführungsplänen erhöht werden.The use of parameters, including parameter markers in ADO, OLE DB, and ODBC applications, can increase the reuse of execution plans.

Warnung

Es ist sicherer, Parameter oder Parametermarkierungen zu verwenden, die vom Endbenutzer eingegebene Werte enthalten, als die Werte in einer Zeichenfolge zu verketten, die dann mithilfe einer API-Datenzugriffsmethode, einer EXECUTE -Anweisung oder einer gespeicherten sp_executesql -Prozedur ausgeführt werden.Using parameters or parameter markers to hold values that are typed by end users is more secure than concatenating the values into a string that is then executed by using either a data access API method, the EXECUTE statement, or the sp_executesql stored procedure.

Die zwei folgenden SELECT -Anweisungen unterscheiden sich lediglich im Hinblick auf die Werte, die in der WHERE -Klausel verglichen werden:The only difference between the following two SELECT statements is the values that are compared in the WHERE clause:

SELECT * 
FROM AdventureWorks2014.Production.Product 
WHERE ProductSubcategoryID = 1;
SELECT * 
FROM AdventureWorks2014.Production.Product 
WHERE ProductSubcategoryID = 4;

Die Ausführungspläne für diese Abfragen unterscheiden sich lediglich hinsichtlich des Werts, der für den Vergleich mit der ProductSubcategoryID -Spalte gespeichert wird.The only difference between the execution plans for these queries is the value stored for the comparison against the ProductSubcategoryID column. Das Ziel von SQL ServerSQL Server, stets zu erkennen, wenn Anweisungen im Prinzip den gleichen Plan generieren, und diesen Plan dann wiederzuverwenden, kann von SQL ServerSQL Server in komplexen Transact-SQLTransact-SQL-Anweisungen manchmal nicht erkannt werden.While the goal is for SQL ServerSQL Server to always recognize that the statements generate essentially the same plan and reuse the plans, SQL ServerSQL Server sometimes does not detect this in complex Transact-SQLTransact-SQL statements.

Wenn Sie Konstanten mithilfe von Parametern von den Transact-SQLTransact-SQL-Anweisungen trennen, unterstützen Sie die relationale Engine dabei, doppelte Pläne zu erkennen.Separating constants from the Transact-SQLTransact-SQL statement by using parameters helps the relational engine recognize duplicate plans. Es gibt folgende Möglichkeiten, um Parameter zu verwenden:You can use parameters in the following ways:

  • Verwenden Sie sp_executesql in Transact-SQLTransact-SQL:In Transact-SQLTransact-SQL , use sp_executesql:

    DECLARE @MyIntParm INT
    SET @MyIntParm = 1
    EXEC sp_executesql
       N'SELECT * 
       FROM AdventureWorks2014.Production.Product 
       WHERE ProductSubcategoryID = @Parm',
       N'@Parm INT',
       @MyIntParm
    

    Diese Methode wird für Transact-SQLTransact-SQL-Skripts, gespeicherte Prozeduren oder Trigger empfohlen, die SQL-Anweisungen dynamisch generieren.This method is recommended for Transact-SQLTransact-SQL scripts, stored procedures, or triggers that generate SQL statements dynamically.

  • ADO, OLE DB und ODBC verwenden Parametermarkierungen.ADO, OLE DB, and ODBC use parameter markers. Parametermarkierungen sind Fragezeichen (?), die eine Konstante in einer SQL-Anweisung ersetzen und an eine Programmvariable gebunden sind.Parameter markers are question marks (?) that replace a constant in an SQL statement and are bound to a program variable. Beispielsweise können Sie in einer ODBC-Anwendung folgende Aktionen ausführen:For example, you would do the following in an ODBC application:

    • Verwenden Sie SQLBindParameter , um eine ganzzahlige Variable an die erste Parametermarkierung in einer SQL-Anweisung zu binden.Use SQLBindParameter to bind an integer variable to the first parameter marker in an SQL statement.
    • Speichern Sie den ganzzahligen Wert in der Variablen.Put the integer value in the variable.
    • Führen Sie die Anweisung aus, und geben Sie dabei die Parametermarkierung (?) an:Execute the statement, specifying the parameter marker (?):
    SQLExecDirect(hstmt, 
       "SELECT * 
       FROM AdventureWorks2014.Production.Product 
       WHERE ProductSubcategoryID = ?",
       SQL_NTS);
    

    Der SQL ServerSQL Server Native Client-OLE DB-Anbieter und der SQL ServerSQL Server Native Client-ODBC-Treiber, die beide mit SQL ServerSQL Server zur Verfügung gestellt werden, verwenden sp_executesql, um Anweisungen an SQL ServerSQL Server zu senden, wenn Parametermarkierungen in Anwendungen verwendet werden.The SQL ServerSQL Server Native Client OLE DB Provider and the SQL ServerSQL Server Native Client ODBC driver included with SQL ServerSQL Server use sp_executesql to send statements to SQL ServerSQL Server when parameter markers are used in applications.

  • Zum Entwerfen von gespeicherten Prozeduren mit vorprogrammierter ParameterverwendungTo design stored procedures, which use parameters by design.

Wenn Sie beim Entwerfen ihrer Anwendungen nicht explizit Parameter in diese einbauen, können Sie auch den SQL ServerSQL Server-Abfrageoptimierer heranziehen, um bestimmte Abfragen mithilfe des Standardverhaltens der einfachen Parametrisierung automatisch zu parametrisieren.If you do not explicitly build parameters into the design of your applications, you can also rely on the SQL ServerSQL Server Query Optimizer to automatically parameterize certain queries by using the default behavior of simple parameterization. Alternativ können Sie erzwingen, dass der Abfrageoptimierer die Parametrisierung aller Abfragen in der Datenbank in Betracht zieht, indem Sie die PARAMETERIZATION-Option der ALTER DATABASE-Anweisung auf FORCED festlegen.Alternatively, you can force the Query Optimizer to consider parameterizing all queries in the database by setting the PARAMETERIZATION option of the ALTER DATABASE statement to FORCED.

Auch wenn die erzwungene Parametrisierung aktiviert ist, kann die einfache Parametrisierung erfolgen.When forced parameterization is enabled, simple parameterization can still occur. Die folgende Abfrage kann beispielsweise gemäß den Regeln der erzwungenen Parametrisierung nicht parametrisiert werden:For example, the following query cannot be parameterized according to the rules of forced parameterization:

SELECT * FROM Person.Address
WHERE AddressID = 1 + 2;

Sie kann jedoch nach den Regeln der einfachen Parametrisierung parametrisiert werden.However, it can be parameterized according to simple parameterization rules. Wenn die erzwungene Parametrisierung einen Fehler erzeugt, wird anschließend die einfache Parametrisierung versucht.When forced parameterization is tried but fails, simple parameterization is still subsequently tried.

Einfache Parametrisierung

Simple Parameterization

In SQL ServerSQL Server wird durch das Verwenden von Parametern oder Parametermarkierungen in Transact-SQL-Anweisungen die Fähigkeit der relationalen Engine verbessert, neue Transact-SQLTransact-SQL-Anweisungen vorhandenen, zuvor kompilierten Ausführungsplänen zuzuordnen.In SQL ServerSQL Server, using parameters or parameter markers in Transact-SQL statements increases the ability of the relational engine to match new Transact-SQLTransact-SQL statements with existing, previously-compiled execution plans.

Warnung

Es ist sicherer, Parameter oder Parametermarkierungen zu verwenden, die vom Endbenutzer eingegebene Werte enthalten, als die Werte in einer Zeichenfolge zu verketten, die dann mithilfe einer API-Datenzugriffsmethode, einer EXECUTE -Anweisung oder einer gespeicherten sp_executesql -Prozedur ausgeführt werden.Using parameters or parameter markers to hold values typed by end users is more secure than concatenating the values into a string that is then executed using either a data access API method, the EXECUTE statement, or the sp_executesql stored procedure.

Wenn eine Transact-SQLTransact-SQL-Anweisung ohne Parameter ausgeführt wird, parametrisiert SQL ServerSQL Server die Anweisung intern, um die Wahrscheinlichkeit zu erhöhen, dass ein übereinstimmender Ausführungsplan gefunden wird.If a Transact-SQLTransact-SQL statement is executed without parameters, SQL ServerSQL Server parameterizes the statement internally to increase the possibility of matching it against an existing execution plan. Dieser Prozess wird als einfache Parametrisierung bezeichnet.This process is called simple parameterization. In SQL ServerSQL Server-Versionen vor 2005 wurde dieser Prozess als automatische Parametrisierung bezeichnet.In SQL ServerSQL Server versions prior to 2005, the process was referred to as auto-parameterization.

Angenommen, die folgende Anweisung wird ausgeführt:Consider this statement:

SELECT * FROM AdventureWorks2014.Production.Product 
WHERE ProductSubcategoryID = 1;

Der Wert 1 am Ende der Anweisung kann als Parameter angegeben werden.The value 1 at the end of the statement can be specified as a parameter. Die relationale Engine erstellt den Ausführungsplan für diesen Batch so, als ob anstelle des Werts 1 ein Parameter angegeben worden wäre.The relational engine builds the execution plan for this batch as if a parameter had been specified in place of the value 1. Aufgrund dieser einfachen Parametrisierung erkennt SQL ServerSQL Server, dass die folgenden beiden Anweisungen im Prinzip den gleichen Ausführungsplan generieren, und verwendet den ersten Plan auch für die zweite Anweisung:Because of this simple parameterization, SQL ServerSQL Server recognizes that the following two statements generate essentially the same execution plan and reuses the first plan for the second statement:

SELECT * FROM AdventureWorks2014.Production.Product 
WHERE ProductSubcategoryID = 1;
SELECT * FROM AdventureWorks2014.Production.Product 
WHERE ProductSubcategoryID = 4;

Bei der Verarbeitung komplexer Transact-SQLTransact-SQL-Anweisungen können für die relationale Engine eventuell Schwierigkeiten bei der Bestimmung der Ausdrücke auftreten, die parametrisiert werden können.When processing complex Transact-SQLTransact-SQL statements, the relational engine may have difficulty determining which expressions can be parameterized. Soll die Wahrscheinlichkeit erhöht werden, dass die relationale Engine Übereinstimmungen zwischen komplexen Transact-SQLTransact-SQL-Anweisungen und vorhandenen, nicht verwendeten Ausführungsplänen erkennt, sollten Sie die Parameter explizit mithilfe von „sp_executesql“ oder Parametermarkierungen angeben.To increase the ability of the relational engine to match complex Transact-SQLTransact-SQL statements to existing, unused execution plans, explicitly specify the parameters using either sp_executesql or parameter markers.

Hinweis

Wenn die arithmetischen Operatoren +, –, *, / oder % zur impliziten oder expliziten Konvertierung von Konstantenwerten der Datentypen „int“, „smallint“, „tinyint“ oder „bigint“ in die Datentypen „float“, „real“, „decimal“ oder „numeric“ verwendet werden, wendet SQL ServerSQL Server spezielle Regeln an, um den Typ und die Genauigkeit der Ausdrucksergebnisse zu berechnen.When the +, -, *, /, or % arithmetic operators are used to perform implicit or explicit conversion of int, smallint, tinyint, or bigint constant values to the float, real, decimal or numeric data types, SQL ServerSQL Server applies specific rules to calculate the type and precision of the expression results. Allerdings unterscheiden sich diese Regeln in Abhängigkeit davon, ob die Abfrage parametrisiert ist oder nicht.However, these rules differ, depending on whether the query is parameterized or not. Daher können gleiche Ausdrücke in Abfragen in einigen Fällen zu unterschiedlichen Ergebnissen führen.Therefore, similar expressions in queries can, in some cases, produce differing results.

Beim Standardverhalten der einfachen Parametrisierung parametrisiert SQL ServerSQL Server eine relativ kleine Klasse von Abfragen.Under the default behavior of simple parameterization, SQL ServerSQL Server parameterizes a relatively small class of queries. Allerdings können Sie angeben, dass mit bestimmten Einschränkungen alle Abfragen in einer Datenbank parametrisiert werden, indem Sie die PARAMETERIZATION -Option des Befehls ALTER DATABASE auf FORCEDfestlegen.However, you can specify that all queries in a database be parameterized, subject to certain limitations, by setting the PARAMETERIZATION option of the ALTER DATABASE command to FORCED. Damit kann die Leistung von Datenbanken verbessert werden, bei denen sehr viele gleichzeitige Abfragen auftreten, indem die Häufigkeit der Abfragekompilierungen verringert wird.Doing so may improve the performance of databases that experience high volumes of concurrent queries by reducing the frequency of query compilations.

Alternativ können Sie angeben, dass eine einzelne Abfrage und alle anderen Abfragen, die in ihrer Syntax gleichwertig sind, und lediglich in ihren Parameterwerten abweichen, parametrisiert werden.Alternatively, you can specify that a single query, and any others that are syntactically equivalent but differ only in their parameter values, be parameterized.

Erzwungene Parametrisierung

Forced Parameterization

Sie können das standardmäßige Parametrisierungsverhalten von SQL ServerSQL Server, die einfache Parametrisierung, überschreiben, indem Sie angeben, dass alle SELECT-, INSERT-, UPDATE- und DELETE-Anweisungen in einer Datenbank mit bestimmten Einschränkungen parametrisiert werden sollen.You can override the default simple parameterization behavior of SQL ServerSQL Server by specifying that all SELECT, INSERT, UPDATE, and DELETE statements in a database be parameterized, subject to certain limitations. Die erzwungene Parametrisierung wird aktiviert, indem die PARAMETERIZATION -Option in der FORCED -Anweisung auf ALTER DATABASE festgelegt wird.Forced parameterization is enabled by setting the PARAMETERIZATION option to FORCED in the ALTER DATABASE statement. Indem sie die Frequenz von Anweisungskompilierungen und -neukompilierungen verringert, kann die erzwungene Parametrisierung die Leistungsfähigkeit bestimmter Datenbanken erhöhen.Forced parameterization may improve the performance of certain databases by reducing the frequency of query compilations and recompilations. Dabei handelt es sich im Allgemeinen um Datenbanken, die einer großen Anzahl gleichzeitiger Abfragen ausgesetzt sind, wie z. B. Point-of-Sale-Anwendungen.Databases that may benefit from forced parameterization are generally those that experience high volumes of concurrent queries from sources such as point-of-sale applications.

Wenn die PARAMETERIZATION -Option auf FORCEDfestgelegt ist, werden während der Kompilierung der Abfrage alle Literalwerte in SELECT-, INSERT-, UPDATE- oder DELETE -Anweisungen, ungeachtet der Form, in der sie übergeben wurden, in Parameter konvertiert.When the PARAMETERIZATION option is set to FORCED, any literal value that appears in a SELECT, INSERT, UPDATE, or DELETE statement, submitted in any form, is converted to a parameter during query compilation. Ausnahmen bilden Literalwerte in folgenden Abfragekonstruktionen:The exceptions are literals that appear in the following query constructs:

  • INSERT...EXECUTE -Anweisungen. Statements
  • Anweisungen innerhalb des Hauptteils von gespeicherten Prozeduren, Triggern oder benutzerdefinierten Funktionen.Statements inside the bodies of stored procedures, triggers, or user-defined functions. In SQL ServerSQL Server werden bereits Abfragepläne für diese Routinen wiederverwendet.SQL ServerSQL Server already reuses query plans for these routines.
  • Vorbereitete Anweisungen, die bereits in der clientbasierten Anwendung parametrisiert wurden.Prepared statements that have already been parameterized on the client-side application.
  • Anweisungen, die XQuery-Methodenaufrufe enthalten, wo die Methode in einem Kontext angezeigt wird, in dem ihre Argumente normalerweise parametrisiert werden, wie beispielsweise die WHERE -Klausel.Statements that contain XQuery method calls, where the method appears in a context where its arguments would typically be parameterized, such as a WHERE clause. Wenn die Methode in einem Kontext angezeigt wird, in dem ihre Argumente normalerweise nicht parametrisiert werden, wird der Rest der Anweisung parametrisiert.If the method appears in a context where its arguments would not be parameterized, the rest of the statement is parameterized.
  • Anweisungen innerhalb eines Transact-SQLTransact-SQL-Cursors.Statements inside a Transact-SQLTransact-SQL cursor. (SELECT -Anweisungen innerhalb von API-Cursorn werden parametrisiert.)(SELECT statements inside API cursors are parameterized.)
  • Als veraltet markierte Abfragekonstrukte.Deprecated query constructs.
  • Eine Anweisung, die im Kontext von ANSI_PADDING oder ANSI_NULLS mit der Einstellung OFFausgeführt wird.Any statement that is run in the context of ANSI_PADDING or ANSI_NULLS set to OFF.
  • Anweisungen mit mehr als 2.097 parametrisierbaren Literalwerten.Statements that contain more than 2,097 literals that are eligible for parameterization.
  • Anweisungen, die auf Variablen verweisen, wie beispielsweise WHERE T.col2 >= @bb.Statements that reference variables, such as WHERE T.col2 >= @bb.
  • Anweisungen mit RECOMPILE -Abfragehinweis.Statements that contain the RECOMPILE query hint.
  • Anweisungen mit COMPUTE -Klauseln.Statements that contain a COMPUTE clause.
  • Anweisungen mit WHERE CURRENT OF -Klauseln.Statements that contain a WHERE CURRENT OF clause.

Außerdem werden die folgenden Abfrageklauseln nicht parametrisiert.Additionally, the following query clauses are not parameterized. Beachten Sie, dass in diesen Fällen nur die Klauseln nicht parametrisiert werden.Note that in these cases, only the clauses are not parameterized. Andere Klauseln in derselben Abfrage können für eine erzwungene Parametrisierung in Frage kommen.Other clauses within the same query may be eligible for forced parameterization.

  • <select_list> in SELECT-Anweisungen.The <select_list> of any SELECT statement. Dies trifft ebenfalls auf SELECT-Listen von Unterabfragen sowie SELECT-Listen innerhalb von INSERT-Anweisungen zu.This includes SELECT lists of subqueries and SELECT lists inside INSERT statements.
  • Unterabfragen mit SELECT -Anweisungen innerhalb von IF -Anweisungen.Subquery SELECT statements that appear inside an IF statement.
  • Die Abfrageklauseln TOP, TABLESAMPLE, HAVING, GROUP BY, ORDER BY, OUTPUT...INTOund FOR XML.The TOP, TABLESAMPLE, HAVING, GROUP BY, ORDER BY, OUTPUT...INTO, or FOR XML clauses of a query.
  • Direkte oder als Teilausdrücke formulierte Argumente der Operatoren OPENROWSET, OPENQUERY, OPENDATASOURCE, OPENXMLsowie aller FULLTEXT -Operatoren.Arguments, either direct or as subexpressions, to OPENROWSET, OPENQUERY, OPENDATASOURCE, OPENXML, or any FULLTEXT operator.
  • Das pattern-Argument und das escape_character-Argument einer LIKE -Klausel.The pattern and escape_character arguments of a LIKE clause.
  • Das style-Argument einer CONVERT -Klausel.The style argument of a CONVERT clause.
  • Integer-Konstanten innerhalb einer IDENTITY -Klausel.Integer constants inside an IDENTITY clause.
  • Über die ODBC-Erweiterungssyntax angegebene Konstanten.Constants specified by using ODBC extension syntax.
  • Vor der Kompilierzeit auf eine Konstante reduzierbare Ausdrücke, die Argumente der Operatoren +, -, *, / und % sind.Constant-foldable expressions that are arguments of the +, -, *, /, and % operators. Um zu ermitteln, ob die erzwungene Parametrisierung in Frage kommt, betrachtet SQL ServerSQL Server einen Ausdruck als vor der Kompilierzeit auf eine Konstante reduzierbar, wenn die beiden folgenden Bedingungen erfüllt sind:When considering eligibility for forced parameterization, SQL ServerSQL Server considers an expression to be constant-foldable when either of the following conditions is true:
    • Der Ausdruck enthält keine Spalten, Variablen oder Unterabfragen.No columns, variables, or subqueries appear in the expression.
    • Der Ausdruck enthält eine CASE -Klausel.The expression contains a CASE clause.
  • Argumente von Abfragehinweisklauseln.Arguments to query hint clauses. Zu diesen gehören das number_of_rows -Argument des FAST -Abfragehinweises, das number_of_processors -Argument des MAXDOP -Abfragehinweises sowie das number-Argument des MAXRECURSION -Abfragehinweises.These include the number_of_rows argument of the FAST query hint, the number_of_processors argument of the MAXDOP query hint, and the number argument of the MAXRECURSION query hint.

Die Parametrisierung wird auf der Ebene der einzelnen Transact-SQLTransact-SQL-Anweisungen ausgeführt,Parameterization occurs at the level of individual Transact-SQLTransact-SQL statements. d. h. die Anweisungen werden nacheinander batchweise parametrisiert.In other words, individual statements in a batch are parameterized. Nach dem Kompilieren wird eine parametrisierte Abfrage ausgeführt – in dem Kontext des Batches, in dem die Abfrage ursprünglich übermittelt wurde.After compiling, a parameterized query is executed in the context of the batch in which it was originally submitted. Wenn ein Ausführungsplan für eine Abfrage zwischengespeichert wird, können Sie anhand der sql-Spalte der dynamischen Verwaltungssicht sys.syscacheobjects ermitteln, ob die Abfrage parametrisiert wurde.If an execution plan for a query is cached, you can determine whether the query was parameterized by referencing the sql column of the sys.syscacheobjects dynamic management view. Wenn eine Abfrage parametrisiert wird, stehen die Namen und Datentypen der Parameter vor dem Text des übergebenen Batches in dieser Spalte, z. B. (@1 tinyint).If a query is parameterized, the names and data types of parameters come before the text of the submitted batch in this column, such as (@1 tinyint).

Hinweis

Parameternamen sind willkürlich.Parameter names are arbitrary. Benutzer bzw. Anwendungen sollten sich nicht auf eine bestimmte Namensreihenfolge verlassen.Users or applications should not rely on a particular naming order. Darüber hinaus kann sich zwischen verschiedenen Versionen von SQL ServerSQL Server und Service Pack-Upgrades Folgendes ändern: Parameternamen, die Auswahl der parametrisierten Literale und der Abstand im parametrisierten Text.Also, the following can change between versions of SQL ServerSQL Server and Service Pack upgrades: Parameter names, the choice of literals that are parameterized, and the spacing in the parameterized text.

ParameterdatentypenData Types of Parameters

Beim Parametrisieren von Literalwerten konvertiert SQL ServerSQL Server die Parameter in folgende Datentypen:When SQL ServerSQL Server parameterizes literals, the parameters are converted to the following data types:

  • Integer-Literale, die von der Größe her in den int-Datentyp passen, werden beim Parametrisieren in int-Werte konvertiert. Größere Integer-Literale, die Teil von Prädikaten mit Vergleichsoperatoren sind (unter anderem <, <=, =, !=, >, >=, , !<, !>, <>, ALL, ANY, SOME, BETWEEN, and IN) werden beim Parametrisieren in numeric(38,0)-Werte konvertiert.Integer literals whose size would otherwise fit within the int data type parameterize to int. Larger integer literals that are parts of predicates that involve any comparison operator (includes <, <=, =, !=, >, >=, , !<, !>, <>, ALL, ANY, SOME, BETWEEN, and IN) parameterize to numeric(38,0). Größere Literale, die nicht Teil von Prädikaten mit Vergleichsoperatoren sind, werden bei der Parametrisierung in numerische Werte mit ausreichenden Ziffern (precision) für ihre Größe und einem Dezimalstellenwert (scale) von 0 konvertiert.Larger literals that are not parts of predicates that involve comparison operators parameterize to numeric whose precision is just large enough to support its size and whose scale is 0.
  • Numerische Festkommaliterale, die Teil von Prädikaten mit Vergleichsoperatoren sind, werden bei der Parametrisierung in numerische Werte mit 38 Ziffern (precision) und einem für ihre Größe ausreichenden Dezimalstellenwert (scale) konvertiert.Fixed-point numeric literals that are parts of predicates that involve comparison operators parameterize to numeric whose precision is 38 and whose scale is just large enough to support its size. Numerische Festkommaliterale, die nicht Teil von Prädikaten mit Vergleichsoperatoren sind, werden bei der Parametrisierung in numerische Werte mit ausreichenden Ziffern (precision) und einem ausreichenden Dezimalstellenwert (scale) für ihre Größe konvertiert.Fixed-point numeric literals that are not parts of predicates that involve comparison operators parameterize to numeric whose precision and scale are just large enough to support its size.
  • Numerische Fließkommaliterale werden bei der Parametrisierung in float(53)-Werte konvertiert.Floating point numeric literals parameterize to float(53).
  • Nicht-Unicode-Zeichenfolgenliterale werden bei der Parametrisierung in varchar(8000)-Werte konvertiert, wenn das Literal 8.000 Zeichen nicht überschreitet, und in varchar(max)-Werte, wenn es 8.000 Zeichen überschreitet.Non-Unicode string literals parameterize to varchar(8000) if the literal fits within 8,000 characters, and to varchar(max) if it is larger than 8,000 characters.
  • Unicode-Zeichenfolgenliterale werden bei der Parametrisierung in nvarchar(4000)-Werte konvertiert, wenn das Literal 4.000 Zeichen nicht überschreitet, und in nvarchar(max)-Werte, wenn es 4.000 Zeichen überschreitet.Unicode string literals parameterize to nvarchar(4000) if the literal fits within 4,000 Unicode characters, and to nvarchar(max) if the literal is larger than 4,000 characters.
  • Binäre Literale werden bei der Parametrisierung in varbinary(8000)-Werte konvertiert, wenn das Literal 8.000 Bytes nicht überschreitet.Binary literals parameterize to varbinary(8000) if the literal fits within 8,000 bytes. Wenn es 8.000 Bytes überschreitet, wird es in einen varbinary(max)-Wert konvertiert.If it is larger than 8,000 bytes, it is converted to varbinary(max).
  • Literale vom Typ „money“ werden bei der Parametrisierung in money-Werte konvertiert.Money type literals parameterize to money.

Richtlinien für die Verwendung der erzwungenen Parametrisierung

Guidelines for Using Forced Parameterization

Berücksichtigen Sie Folgendes, wenn Sie die PARAMETERIZATION -Option auf FORCED festlegen:Consider the following when you set the PARAMETERIZATION option to FORCED:

  • Die erzwungene Parametrisierung konvertiert die literalen Konstanten einer Abfrage, sobald diese kompiliert wird, tatsächlich in Parameter.Forced parameterization, in effect, changes the literal constants in a query to parameters when compiling a query. Daher ist es möglich, dass der Abfrageoptimierer nicht die optimalen Abfragepläne auswählt.Therefore, the Query Optimizer might choose suboptimal plans for queries. Insbesondere verringert sich die Wahrscheinlichkeit, dass der Abfrageoptimierer eine Übereinstimmung zwischen der Abfrage und der richtigen indizierten Sicht oder dem Index für eine berechnete Spalte findet.In particular, the Query Optimizer is less likely to match the query to an indexed view or an index on a computed column. Außerdem wählt der Abfrageoptimierer möglicherweise auch für Abfragen für partitionierte Tabellen und verteilte partitionierte Sichten nicht optimale Abfragepläne aus.It may also choose suboptimal plans for queries posed on partitioned tables and distributed partitioned views. Die erzwungene Parametrisierung sollte deshalb nicht in Umgebungen verwendet werden, die sich stark auf indexierte Sichten oder Indizes für berechnete Spalten stützen.Forced parameterization should not be used for environments that rely heavily on indexed views and indexes on computed columns. Im Allgemeinen sollte die PARAMETERIZATION FORCED -Option nur von erfahrenen Datenbankadministratoren verwendet werden, und auch dann nur, wenn diese sichergestellt haben, dass die erzwungene Parametrisierung die Leistung der Datenbank nicht beeinträchtigt.Generally, the PARAMETERIZATION FORCED option should only be used by experienced database administrators after determining that doing this does not adversely affect performance.
  • Verteilte Abfragen, die auf mehrere Datenbanken verweisen, sind für die erzwungene Parametrisierung geeignet, solange die PARAMETERIZATION -Option in der Datenbank auf FORCED festgelegt wird, in deren Kontext die Abfrage ausgeführt wird.Distributed queries that reference more than one database are eligible for forced parameterization as long as the PARAMETERIZATION option is set to FORCED in the database whose context the query is running.
  • Wenn die PARAMETERIZATION -Option auf FORCED festgelegt wird, werden alle Abfragepläne aus dem Plancache der Datenbank geleert, mit Ausnahme derer, die gerade kompiliert, erneut kompiliert oder ausgeführt werden.Setting the PARAMETERIZATION option to FORCED flushes all query plans from the plan cache of a database, except those that currently are compiling, recompiling, or running. Die Pläne der Abfragen, die während der Einstellungsänderung kompiliert, erneut kompiliert oder ausgeführt werden, werden beim nächsten Ausführen der Abfrage parametrisiert.Plans for queries that are compiling or running during the setting change are parameterized the next time the query is executed.
  • Das Festlegen der PARAMETERIZATION -Option ist ein Onlinevorgang, d.h., es sind keine exklusiven Sperren auf Datenbankebene erforderlich.Setting the PARAMETERIZATION option is an online operation that it requires no database-level exclusive locks.
  • Die aktuelle Einstellung der PARAMETERIZATION -Option wird beim erneuten Anfügen oder Wiederherstellen einer Datenbank beibehalten.The current setting of the PARAMETERIZATION option is preserved when reattaching or restoring a database.

Sie können das Verhalten der erzwungenen Parametrisierung überschreiben, indem Sie angeben, dass für eine einzelne Abfrage und für alle anderen Abfragen, die syntaktisch äquivalent sind und sich nur in ihren Parameterwerten unterscheiden, die einfache Parametrisierung versucht werden soll.You can override the behavior of forced parameterization by specifying that simple parameterization be attempted on a single query, and any others that are syntactically equivalent but differ only in their parameter values. Im Gegensatz dazu können Sie angeben, dass die erzwungene Parametrisierung nur für einen Satz von syntaktisch äquivalenten Abfragen versucht werden soll, selbst wenn die erzwungene Parametrisierung in der Datenbank deaktiviert ist.Conversely, you can specify that forced parameterization be attempted on only a set of syntactically equivalent queries, even if forced parameterization is disabled in the database. Zu diesem Zweck werdenPlanhinweislisten verwendet. Plan guides are used for this purpose.

Hinweis

Wird die PARAMETERIZATION-Option auf FORCED festgelegt, unterscheiden sich Fehlermeldungen möglicherweise, wenn die Option PARAMETERIZATION auf SIMPLE festgelegt ist: Eventuell werden mehr Fehlermeldungen unter erzwungener Parametrisierung ausgegeben, und die Zeilennummern, in denen die Fehler aufgetreten sind, werden möglicherweise falsch gemeldet.When the PARAMETERIZATION option is set to FORCED, the reporting of error messages may differ from when the PARAMETERIZATION option is set to SIMPLE: multiple error messages may be reported under forced parameterization, where fewer messages would be reported under simple parameterization, and the line numbers in which errors occur may be reported incorrectly.

Vorbereiten von SQL-AnweisungenPreparing SQL Statements

Die relationale Engine von SQL ServerSQL Server bietet vollständige Unterstützung für die Vorbereitung von Transact-SQLTransact-SQL-Anweisungen vor ihrer Ausführung.The SQL ServerSQL Server relational engine introduces full support for preparing Transact-SQLTransact-SQL statements before they are executed. Wenn eine Anwendung eine Transact-SQLTransact-SQL-Anweisung mehrfach ausführen muss, kann mithilfe der Datenbank-API Folgendes erreicht werden:If an application has to execute an Transact-SQLTransact-SQL statement several times, it can use the database API to do the following:

  • Einmaliges Vorbereiten der Anweisung.Prepare the statement once. Mit diesem Schritt wird die Transact-SQLTransact-SQL-Anweisung zu einem Ausführungsplan kompiliert.This compiles the Transact-SQLTransact-SQL statement into an execution plan.
  • Ausführen des vorkompilierten Ausführungsplans immer dann, wenn die Anweisung ausgeführt werden muss.Execute the precompiled execution plan every time it has to execute the statement. Auf diese Weise muss die Transact-SQLTransact-SQL-Anweisung nach der ersten Ausführung nicht jedes Mal erneut kompiliert werden.This prevents having to recompile the Transact-SQLTransact-SQL statement on each execution after the first time.
    Das Vorbereiten und Ausführen von Anweisungen wird durch API-Funktionen und -Methoden gesteuert.Preparing and executing statements is controlled by API functions and methods. Es ist kein Teil der Transact-SQLTransact-SQL-Sprache.It is not part of the Transact-SQLTransact-SQL language. Das Vorbereiten/Ausführen-Modell für die Ausführung von Transact-SQLTransact-SQL-Anweisungen wird von dem SQL ServerSQL Server Native Client-OLE DB-Anbieter und dem SQL ServerSQL Server Native Client-ODBC-Treiber unterstützt.The prepare/execute model of executing Transact-SQLTransact-SQL statements is supported by the SQL ServerSQL Server Native Client OLE DB Provider and the SQL ServerSQL Server Native Client ODBC driver. Bei einer Vorbereitungsanforderung sendet der Anbieter oder der Treiber die Anweisung zusammen mit der Anforderung zur Vorbereitung der Anweisung an SQL ServerSQL Server.On a prepare request, either the provider or the driver sends the statement to SQL ServerSQL Server with a request to prepare the statement. Von SQL ServerSQL Server wird ein Ausführungsplan kompiliert und ein Handle für diesen Plan an den Anbieter oder Treiber zurückgegeben.SQL ServerSQL Server compiles an execution plan and returns a handle for that plan to the provider or driver. Bei einer Ausführungsanforderung sendet der Anbieter bzw. Treiber eine Anforderung an den Server, den dem Handle zugeordneten Plan auszuführen.On an execute request, either the provider or the driver sends the server a request to execute the plan that is associated with the handle.

Vorbereitete Anweisungen können nicht zum Erstellen von temporären Objekten in SQL ServerSQL Server verwendet werden.Prepared statements cannot be used to create temporary objects on SQL ServerSQL Server. Vorbereitete Anweisungen können nicht auf gespeicherte Systemprozeduren verweisen, die temporäre Objekte, wie z. B. temporäre Tabellen, erstellen.Prepared statements cannot reference system stored procedures that create temporary objects, such as temporary tables. Diese Prozeduren müssen direkt ausgeführt werden.These procedures must be executed directly.

Durch übermäßige Verwendung des Vorbereiten/Ausführen-Modells kann die Leistung beeinträchtigt werden.Excess use of the prepare/execute model can degrade performance. Wenn eine Anweisung nur ein Mal ausgeführt wird, wird durch eine direkte Ausführung nur ein Netzwerkroundtrip zum Server benötigt.If a statement is executed only once, a direct execution requires only one network round-trip to the server. Das Vorbereiten und Ausführen einer Transact-SQLTransact-SQL-Anweisung, die nur ein Mal ausgeführt wird, erfordert einen zusätzlichen Netzwerkroundtrip: einen Trip zur Vorbereitung und einen Trip zur Ausführung der Anweisung.Preparing and executing an Transact-SQLTransact-SQL statement executed only one time requires an extra network round-trip; one trip to prepare the statement and one trip to execute it.

Das Vorbereiten einer Anweisung ist effizienter, wenn Parametermarkierungen verwendet werden.Preparing a statement is more effective if parameter markers are used. Nehmen Sie z.B. an, eine Anwendung soll gelegentlich Produktinformationen aus der AdventureWorks -Beispieldatenbank abrufen.For example, assume that an application is occasionally asked to retrieve product information from the AdventureWorks sample database. Es gibt zwei Möglichkeiten, wie die Anwendung diese Aufgabe ausführen kann.There are two ways the application can do this.

Die erste Möglichkeit besteht darin, dass die Anwendung für jedes angeforderte Produkt eine eigene Abfrage ausführt:Using the first way, the application can execute a separate query for each product requested:

SELECT * FROM AdventureWorks2014.Production.Product
WHERE ProductID = 63;

Die zweite Möglichkeit umfasst folgende Schritte:Using the second way, the application does the following:

  1. Die Anwendung bereitet eine Anweisung vor, die die Parametermarkierung (?) enthält:Prepares a statement that contains a parameter marker (?):
    SELECT * FROM AdventureWorks2014.Production.Product  
    WHERE ProductID = ?;
    
  2. Die Anwendung bindet eine Programmvariable an die Parametermarkierung.Binds a program variable to the parameter marker.
  3. Die Anwendung füllt die gebundene Variable mit dem Schlüsselwert und führt die Anweisung aus, sobald die Produktinformationen benötigt werden.Each time product information is needed, fills the bound variable with the key value and executes the statement.

Die zweite Methode ist effizienter, sobald die Anweisung mehr als drei Mal ausgeführt wird.The second way is more efficient when the statement is executed more than three times.

In SQL ServerSQL Server bietet das Vorbereiten/Ausführen-Modell aufgrund der Art und Weise, wie Ausführungspläne von SQL ServerSQL Server wiederverwendet werden, keine erheblichen Leistungsvorteile gegenüber der direkten Ausführung.In SQL ServerSQL Server, the prepare/execute model has no significant performance advantage over direct execution, because of the way SQL ServerSQL Server reuses execution plans. SQL ServerSQL Server besitzt effiziente Algorithmen zur Ermittlung von Übereinstimmungen zwischen aktuellen Transact-SQLTransact-SQL-Anweisungen und Ausführungsplänen, die für vorhergehende Ausführungen derselben Transact-SQLTransact-SQL-Anweisung generiert wurden.has efficient algorithms for matching current Transact-SQLTransact-SQL statements with execution plans that are generated for prior executions of the same Transact-SQLTransact-SQL statement. Wenn eine Anwendung eine SQL ServerSQL Server-Anweisung mit Parametermarkierungen mehrfach ausführt, verwendet Transact-SQLTransact-SQL den Ausführungsplan der ersten Ausführung für die zweite und alle folgenden Ausführungen erneut (es sei denn, der Plan wird aus dem Plancache entfernt).If an application executes a Transact-SQLTransact-SQL statement with parameter markers multiple times, SQL ServerSQL Server will reuse the execution plan from the first execution for the second and subsequent executions (unless the plan ages from the plan cache). Das Vorbereiten/Ausführen-Modell bietet jedoch weiterhin die folgenden Vorteile:The prepare/execute model still has these benefits:

  • Das Suchen eines Ausführungsplans anhand eines identifizierenden Handles ist effizienter als die Algorithmen, die für das Ermitteln einer übereinstimmenden Transact-SQLTransact-SQL-Anweisung mit vorhandenen Ausführungsplänen verwendet werden.Finding an execution plan by an identifying handle is more efficient than the algorithms used to match an Transact-SQLTransact-SQL statement to existing execution plans.
  • Die Anwendung kann steuern, wann der Ausführungsplan erstellt, und wann er wiederverwendet werden soll.The application can control when the execution plan is created and when it is reused.
  • Das Vorbereiten/Ausführen-Modell kann auf andere Datenbanken portiert werden, einschließlich früherer Versionen von SQL ServerSQL Server.The prepare/execute model is portable to other databases, including earlier versions of SQL ServerSQL Server.

ParameterermittlungParameter Sniffing

Die „Parameterermittlung“ bezieht sich auf einen Prozess, wobei SQL ServerSQL Server die aktuellen Parameter während der Kompilierung oder Neukompilierung ermittelt und diese an den Abfrageoptimierer übermittelt, sodass sie zum Generieren potenziell effizienter Abfrageausführungspläne verwendet werden können."Parameter sniffing" refers to a process whereby SQL ServerSQL Server "sniffs" the current parameter values during compilation or recompilation, and passes it along to the Query Optimizer so that they can be used to generate potentially more efficient query execution plans.

Parameterwerte werden während der Kompilierung oder Neukompilierung für die folgenden Batchtypen ermittelt:Parameter values are sniffed during compilation or recompilation for the following types of batches:

  • Gespeicherte ProzedurenStored procedures
  • Abfragen, die über „sp_executesql“ übermittelt werdenQueries submitted via sp_executesql
  • Vorbereitete AbfragenPrepared queries

Weitere Informationen zur Problembehandlung bei fehlerhafter Parameterermittlung finden Sie unter Problembehandlung bei Abfragen mit parameterempfindlichem Abfrageausführungsplan.For more information on troubleshooting bad parameter sniffing issues, see Troubleshoot queries with parameter-sensitive query execution plan issues.

Hinweis

Für Abfragen, die den RECOMPILE-Hinweis verwenden, werden jeweils die Parameterwerte und aktuellen Werte der lokalen Variablen ermittelt.For queries using the RECOMPILE hint, both parameter values and current values of local variables are sniffed. Die ermittelten Werte (der Parameter und lokalen Variablen) sind die, die an dem Ort direkt vor der Anweisung mit dem RECOMPILE-Hinweis vorhanden sind.The values sniffed (of parameters and local variables) are those that exist at the place in the batch just before the statement with the RECOMPILE hint. Im Gegensatz dazu werden bei Parametern die Werte, die innerhalb des Batchaufrufs übermittelt werden, nicht geprüft.In particular, for parameters, the values that came along with the batch invocation call are not sniffed.

Parallele AbfrageverarbeitungParallel Query Processing

SQL ServerSQL Server ermöglicht parallele Abfragen, um die Abfrageausführung und Indexvorgänge für Computer zu optimieren, die über mehrere Mikroprozessoren (CPUs) verfügen.provides parallel queries to optimize query execution and index operations for computers that have more than one microprocessor (CPU). Da SQL ServerSQL Server mehrere Betriebssystem-Arbeitsthreads verwenden kann, um eine Abfrage oder einen Indexvorgang parallel auszuführen, kann der betreffende Vorgang schnell und effizient ausgeführt werden.Because SQL ServerSQL Server can perform a query or index operation in parallel by using several operating system worker threads, the operation can be completed quickly and efficiently.

Während der Abfrageoptimierung sucht SQL ServerSQL Server nach Abfragen oder Indexvorgängen, für die eine parallele Ausführung vorteilhaft ist.During query optimization, SQL ServerSQL Server looks for queries or index operations that might benefit from parallel execution. Für diese Abfragen fügt SQL ServerSQL Server Verteilungsoperatoren in den Abfrageausführungsplan ein, um die Abfrage für die parallele Ausführung vorzubereiten.For these queries, SQL ServerSQL Server inserts exchange operators into the query execution plan to prepare the query for parallel execution. Ein Verteilungsoperator ist ein Operator in einem Plan für die Abfrageausführung, der die Prozessverwaltung, die Neuverteilung der Daten und die Ablaufsteuerung ermöglicht.An exchange operator is an operator in a query execution plan that provides process management, data redistribution, and flow control. Der Verteilungsoperator schließt die logischen Operatoren Distribute Streams, Repartition Streamsund Gather Streams als Untertypen ein. Einer oder mehrere dieser Operatoren können in der Showplanausgabe eines Abfrageplans für eine parallele Abfrage enthalten sein.The exchange operator includes the Distribute Streams, Repartition Streams, and Gather Streams logical operators as subtypes, one or more of which can appear in the Showplan output of a query plan for a parallel query.

Wichtig

Bestimmte Konstrukte verhindern, dass SQL ServerSQL Server Parallelität für den gesamten Ausführungsplan oder Teile davon nutzen kann.Certain constructs inhibit SQL ServerSQL Server's ability to leverage parallelism on the entire execution plan, or parts or the execution plan.

Zu den Konstrukten, die Parallelität verhindern, gehören:Constructs that inhibit parallelism include:

Nach dem Einfügen eines Verteilungsoperators ist das Ergebnis ein Plan für eine parallele Abfrageausführung.After exchange operators are inserted, the result is a parallel-query execution plan. Ein Plan für die parallele Abfrageausführung kann mehrere Arbeitsthreads verwenden.A parallel-query execution plan can use more than one worker thread. Ein serieller Ausführungsplan, der von einer nicht parallelen Abfrage verwendet wird, verwendet nur einen Arbeitsthread bei seiner Ausführung.A serial execution plan, used by a nonparallel query, uses only one worker thread for its execution. Die tatsächliche Anzahl der Arbeitsthreads, die von einer parallelen Abfrage verwendet werden, wird während der Initialisierung der Abfrageplanausführung bestimmt und durch die Komplexität des Plans und den Grad der Parallelität bestimmt.The actual number of worker threads used by a parallel query is determined at query plan execution initialization and is determined by the complexity of the plan and the degree of parallelism. Der Grad der Parallelität bestimmt die maximal verwendete Anzahl von CPUs; er bezieht sich nicht auf die Anzahl der verwendeten Arbeitsthreads.Degree of parallelism determines the maximum number of CPUs that are being used; it does not mean the number of worker threads that are being used. Der Wert für den Grad der Parallelität wird auf Serverebene festgelegt und kann mithilfe der gespeicherten Systemprozedur „sp_configure“ geändert werden.The degree of parallelism value is set at the server level and can be modified by using the sp_configure system stored procedure. Sie können diesen Wert für einzelne Abfrage- oder Indexanweisungen überschreiben, indem Sie den MAXDOP -Abfragehinweis oder die MAXDOP -Indexoption angeben.You can override this value for individual query or index statements by specifying the MAXDOP query hint or MAXDOP index option.

Der SQL ServerSQL Server-Abfrageoptimierer verwendet keinen parallelen Ausführungsplan für eine Abfrage, wenn eine der folgenden Bedingungen zutrifft:The SQL ServerSQL Server Query Optimizer does not use a parallel execution plan for a query if any one of the following conditions is true:

  • Die Kosten für die serielle Ausführung der Abfrage sind nicht hoch genug, um einen parallelen Ausführungsplan zu rechtfertigen.The serial execution cost of the query is not high enough to consider an alternative, parallel execution plan.
  • Ein serieller Ausführungsplan wird für die betreffende Abfrage als schneller erachtet als jeder mögliche parallele Ausführungsplan.A serial execution plan is considered faster than any possible parallel execution plan for the particular query.
  • Die Abfrage enthält skalare oder relationale Operatoren, die nicht parallel ausgeführt werden können.The query contains scalar or relational operators that cannot be run in parallel. Bestimmte Operatoren können verursachen, dass ein Abschnitt des Ausführungsplans oder der gesamte Plan im seriellen Modus ausgeführt wird.Certain operators can cause a section of the query plan to run in serial mode, or the whole plan to run in serial mode.

Grad der Parallelität

Degree of parallelism

SQL ServerSQL Server erkennt automatisch den am besten geeigneten Grad an Parallelität für jede Instanz einer parallelen Abfrageausführung oder eines DDL-Indizierungsvorgangs (Data Definition Language).automatically detects the best degree of parallelism for each instance of a parallel query execution or index data definition language (DDL) operation. Dazu werden die folgenden Kriterien untersucht:It does this based on the following criteria:

  1. Wird SQL ServerSQL Server auf einem Computer mit mehreren Mikroprozessoren (oder CPUs) ausgeführt wie z. B. auf einem symmetrischen Multiprozessorcomputer (Symmetric Multiprocessing, SMP)?Whether SQL ServerSQL Server is running on a computer that has more than one microprocessor or CPU, such as a symmetric multiprocessing computer (SMP).
    Nur Computer mit mehreren CPUs können parallele Abfragen verwenden.Only computers that have more than one CPU can use parallel queries.

  2. Sind ausreichend Arbeitsthreads verfügbar?Whether sufficient worker threads are available.
    Jeder Abfrage- oder Indexvorgang setzt zu seiner Ausführung eine bestimmte Anzahl von Arbeitsthreads voraus.Each query or index operation requires a certain number of worker threads to execute. Das Ausführen eines parallelen Plans erfordert mehr Arbeitsthreads als ein serieller Plan, und die Anzahl der erforderlichen Arbeitsthreads steigt mit dem Grad der Parallelität.Executing a parallel plan requires more worker threads than a serial plan, and the number of required worker threads increases with the degree of parallelism. Wenn die Arbeitsthreadanforderung des parallelen Plans für einen bestimmten Grad der Parallelität nicht erfüllt werden kann, reduziert SQL Server-Datenbank-EngineSQL Server Database Engine den Grad an Parallelität automatisch oder verwirft den parallelen Plan in dem angegebenen Arbeitsauslastungskontext.When the worker thread requirement of the parallel plan for a specific degree of parallelism cannot be satisfied, the SQL Server-Datenbank-EngineSQL Server Database Engine decreases the degree of parallelism automatically or completely abandons the parallel plan in the specified workload context. Stattdessen wird der serielle Plan (ein Arbeitsthread) ausgeführt.It then executes the serial plan (one worker thread).

  3. Welcher Abfragetyp oder Indexvorgangstyp soll ausgeführt werden?The type of query or index operation executed.
    Indexvorgänge, die einen Index erstellen oder neu erstellen oder einen gruppierten Index löschen, sowie Abfragen, die sehr viele CPU-Zyklen beanspruchen, eignen sich am besten für einen parallelen Plan.Index operations that create or rebuild an index, or drop a clustered index and queries that use CPU cycles heavily are the best candidates for a parallel plan. So sind z. B. Joins großer Tabellen, umfassende Aggregationen und Sortierungen großer Resultsets gut geeignet.For example, joins of large tables, large aggregations, and sorting of large result sets are good candidates. Für einfache Abfragen, die häufig in transaktionsverarbeitenden Anwendungen eingesetzt werden, wird der zusätzliche Aufwand, der für die Koordinierung einer parallelen Abfrageausführung erforderlich ist, durch die erwartete Leistungssteigerung in der Regel nicht gerechtfertigt.Simple queries, frequently found in transaction processing applications, find the additional coordination required to execute a query in parallel outweigh the potential performance boost. Um zu ermitteln, für welche Abfragen die parallele Ausführung sinnvoll ist und für welche dies nicht gilt, vergleicht SQL Server-Datenbank-EngineSQL Server Database Engine die geschätzten Kosten für die Ausführung der Abfrage oder des Indexvorgangs mithilfe des cost threshold for parallelism-Werts (Kostenschwellenwert für Parallelität).To distinguish between queries that benefit from parallelism and those that do not benefit, the SQL Server-Datenbank-EngineSQL Server Database Engine compares the estimated cost of executing the query or index operation with the cost threshold for parallelism value. Benutzer können den Standardwert 5 mithilfe von sp_configure ändern, wenn durch einen richtigen Test ermittelt wurde, dass ein anderer Wert besser für die ausgeführte Workload geeignet ist.Users can change the default value of 5 using sp_configure if proper testing found that a different value is better suited for the running workload.

  4. Gibt es eine ausreichende Anzahl von zu verarbeitenden Zeilen?Whether there are a sufficient number of rows to process.
    Wenn der Abfrageoptimierer ermittelt, dass die Anzahl der Zeilen zu niedrig ist, werden keine Verteilungsoperatoren eingesetzt, um die Zeilen zu verteilen.If the Query Optimizer determines that the number of rows is too low, it does not introduce exchange operators to distribute the rows. Demzufolge werden die Operatoren seriell ausgeführt.Consequently, the operators are executed serially. Durch das Ausführen der Operatoren in einem seriellen Plan werden Situationen vermieden, in denen die Kosten für Start, Verteilung und Koordinierung den Nutzen übersteigen, der durch die parallele Ausführung der Operatoren erzielt würde.Executing the operators in a serial plan avoids scenarios when the startup, distribution, and coordination costs exceed the gains achieved by parallel operator execution.

  5. Sind aktuelle Verteilungsstatistiken verfügbar?Whether current distribution statistics are available.
    Wenn der höchste Grad der Parallelität nicht möglich ist, werden zunächst niedrigere Grade in Betracht gezogen, bevor der parallele Plan verworfen wird.If the highest degree of parallelism is not possible, lower degrees are considered before the parallel plan is abandoned.
    Wenn Sie z. B. einen gruppierten Index für eine Sicht erstellen, können die Statistiken nicht ausgewertet werden, weil der gruppierte Index noch nicht vorhanden ist.For example, when you create a clustered index on a view, distribution statistics cannot be evaluated, because the clustered index does not yet exist. In diesem Fall kann SQL Server-Datenbank-EngineSQL Server Database Engine nicht den höchsten Grad der Parallelität für den Indexvorgang bereitstellen.In this case, the SQL Server-Datenbank-EngineSQL Server Database Engine cannot provide the highest degree of parallelism for the index operation. Allerdings können einige Vorgänge, wie z. B. das Sortieren und Scannen, von der parallelen Ausführung profitieren.However, some operators, such as sorting and scanning, can still benefit from parallel execution.

Hinweis

Parallele Indexvorgänge sind nur in den Editionen SQL ServerSQL Server Enterprise, Developer und Evaluation verfügbar.Parallel index operations are only available in SQL ServerSQL Server Enterprise, Developer, and Evaluation editions.

Zur Ausführungszeit ermittelt SQL Server-Datenbank-EngineSQL Server Database Engine, ob die aktuelle Systemlast und die oben beschriebenen Konfigurationsinformationen die parallele Ausführung zulassen.At execution time, the SQL Server-Datenbank-EngineSQL Server Database Engine determines whether the current system workload and configuration information previously described allow for parallel execution. Wenn die parallele Ausführung gerechtfertigt ist, ermittelt SQL Server-Datenbank-EngineSQL Server Database Engine die optimale Anzahl von Arbeitsthreads und verteilt dann die Ausführung des parallelen Plans auf diese Arbeitsthreads.If parallel execution is warranted, the SQL Server-Datenbank-EngineSQL Server Database Engine determines the optimal number of worker threads and spreads the execution of the parallel plan across those worker threads. Wenn die parallele Ausführung eines Abfrage- oder Indexvorgangs mit mehreren Arbeitsthreads gestartet wird, wird dieselbe Anzahl an Arbeitsthreads bis zur Beendigung des Vorgangs verwendet.When a query or index operation starts executing on multiple worker threads for parallel execution, the same number of worker threads is used until the operation is completed. SQL Server-Datenbank-EngineSQL Server Database Engine bestimmt die optimale Anzahl von Arbeitsthreads jedes Mal neu, wenn ein Ausführungsplan aus dem Plancache abgerufen wird.The SQL Server-Datenbank-EngineSQL Server Database Engine re-examines the optimal number of worker thread decisions every time an execution plan is retrieved from the plan cache. Bei einer Ausführung einer Abfrage könnte z. B. ein serieller Plan verwendet werden, bei einer späteren Ausführung derselben Abfrage ein paralleler Plan, der drei Arbeitsthreads verwendet, und bei der dritten Ausführung dieser Abfrage ein paralleler Plan, der vier Arbeitsthreads verwendet.For example, one execution of a query can result in the use of a serial plan, a later execution of the same query can result in a parallel plan using three worker threads, and a third execution can result in a parallel plan using four worker threads.

In einem parallelen Abfrageausführungsplan werden die Vorgänge zum Einfügen, Aktualisieren und Löschen seriell ausgeführt.In a parallel query execution plan, the insert, update, and delete operators are executed serially. Jedoch können die WHERE-Klausel einer UPDATE- oder einer DELETE-Anweisung oder der SELECT-Teil einer INSERT-Anweisung parallel ausgeführt werden.However, the WHERE clause of an UPDATE or a DELETE statement, or the SELECT part of an INSERT statement may be executed in parallel. Die eigentlichen Datenänderungen werden anschließend seriell auf die Datenbank angewendet.The actual data changes are then serially applied to the database.

Statische Cursor und keysetgesteuerte Cursor können durch parallele Ausführungspläne aufgefüllt werden.Static and keyset-driven cursors can be populated by parallel execution plans. Das spezifische Verhalten dynamischer Cursor kann jedoch nur durch die serielle Ausführung gewährleistet werden.However, the behavior of dynamic cursors can be provided only by serial execution. Für eine Abfrage, die Teil eines dynamischen Cursors ist, generiert der Abfrageoptimierer immer einen seriellen Ausführungsplan.The Query Optimizer always generates a serial execution plan for a query that is part of a dynamic cursor.

Überschreiben der Grade der ParallelitätOverriding Degrees of Parallelism

Mithilfe der Serverkonfigurationsoption Max. Grad an Parallelität (MAXDOP) (ALTER DATABASE SCOPED CONFIGURATION in SQL-DatenbankSQL Database ) kann die Anzahl der Prozessoren beschränkt werden, die bei der Ausführung paralleler Pläne verwendet werden.You can use the max degree of parallelism (MAXDOP) server configuration option (ALTER DATABASE SCOPED CONFIGURATION on SQL-DatenbankSQL Database ) to limit the number of processors to use in parallel plan execution. Die Option „Max. Grad an Parallelität“ kann jedoch für einzelne Abfrage- und Indexvorgangsanweisungen überschrieben werden, indem der MAXDOP-Abfragehinweis oder die MAXDOP-Indexoption angegeben wird.The max degree of parallelism option can be overridden for individual query and index operation statements by specifying the MAXDOP query hint or MAXDOP index option. MAXDOP bietet mehr Kontrolle über einzelne Abfrage- und Indexvorgänge.MAXDOP provides more control over individual queries and index operations. Sie können z.B. die MAXDOP-Option verwenden, um durch Erhöhen oder Reduzieren eine Steuerung der Anzahl der einem Onlineindexvorgang zugewiesenen Prozessoren zu bewirken.For example, you can use the MAXDOP option to control, by increasing or reducing, the number of processors dedicated to an online index operation. Auf diese Weise können Sie die Ressourcen, die von dem Indexvorgang verwendet werden, mit den Ressourcen gleichzeitiger Benutzer ausgleichen.In this way, you can balance the resources used by an index operation with those of the concurrent users.

Wenn die Option „Max. Grad an Parallelität“ auf 0 (Standard) festgelegt wurde, kann SQL ServerSQL Server alle verfügbaren Prozessoren (maximal 64) zur Ausführung paralleler Pläne verwenden.Setting the max degree of parallelism option to 0 (default) enables SQL ServerSQL Server to use all available processors up to a maximum of 64 processors in a parallel plan execution. Obwohl SQL ServerSQL Server ein Laufzeitziel von 64 logischen Prozessoren festlegt, wenn MAXDOP auf 0 festgelegt ist, kann falls nötig ein anderer Wert manuell festgelegt werden.Although SQL ServerSQL Server sets a runtime target of 64 logical processors when MAXDOP option is set to 0, a different value can be manually set if needed. Wenn MAXDOP für Abfragen und Indizes auf 0 (null) festgelegt wurde, kann SQL ServerSQL Server alle verfügbaren Prozessoren (maximal 64) zur Ausführung paralleler Pläne für die jeweiligen Abfragen oder Indizes verwenden.Setting MAXDOP to 0 for queries and indexes allows SQL ServerSQL Server to use all available processors up to a maximum of 64 processors for the given queries or indexes in a parallel plan execution. MAXDOP ist kein erzwungener Wert für alle parallelen Abfragen, sondern eher ein Ziel mit Vorbehalt für alle Abfragen, die für die Parallelität qualifiziert sind.MAXDOP is not an enforced value for all parallel queries, but rather a tentative target for all queries eligible for parallelism. Das bedeutet, dass wenn nicht genügend Arbeitsthreads zur Laufzeit vorhanden sind, eine Abfrage möglicherweise mit einem niedrigeren Grad der Parallelität als die MAXDOP-Serverkonfigurationsoption ausgeführt wird.This means that if not enough worker threads are available at runtime, a query may execute with a lower degree of parallelism than the MAXDOP server configuration option.

Bewährte Methoden zum Konfigurieren von MAXDOP finden Sie im Microsoft Support-Artikel.Refer to this Microsoft Support Article for best practices on configuring MAXDOP.

Beispiel für eine parallele AbfrageParallel Query Example

In der folgenden Abfrage wird die Anzahl der Bestellungen gezählt, die in einem bestimmten Quartal, beginnend mit dem 1. April 2000, aufgegeben wurden und in denen mindestens ein Artikel der Bestellung vom Kunden erst nach dem angekündigten Datum empfangen wurde.The following query counts the number of orders placed in a specific quarter, starting on April 1, 2000, and in which at least one line item of the order was received by the customer later than the committed date. Die Abfrage listet die Anzahl dieser Bestellungen gruppiert nach Priorität der Bestellung und in aufsteigender Reihenfolge der Priorität auf.This query lists the count of such orders grouped by each order priority and sorted in ascending priority order.

In diesem Beispiel werden erfundene Tabellen- und Spaltennamen verwendet.This example uses theoretical table and column names.

SELECT o_orderpriority, COUNT(*) AS Order_Count
FROM orders
WHERE o_orderdate >= '2000/04/01'
   AND o_orderdate < DATEADD (mm, 3, '2000/04/01')
   AND EXISTS
         (
          SELECT *
            FROM    lineitem
            WHERE l_orderkey = o_orderkey
               AND l_commitdate < l_receiptdate
         )
   GROUP BY o_orderpriority
   ORDER BY o_orderpriority

Nehmen Sie an, dass die folgenden Indizes für die lineitem- und die orders-Tabelle definiert werden:Assume the following indexes are defined on the lineitem and orders tables:

CREATE INDEX l_order_dates_idx 
   ON lineitem
      (l_orderkey, l_receiptdate, l_commitdate, l_shipdate)

CREATE UNIQUE INDEX o_datkeyopr_idx
   ON ORDERS
      (o_orderdate, o_orderkey, o_custkey, o_orderpriority)

Im Folgenden sehen Sie einen möglichen parallelen Plan, der für die zuvor beschriebene Abfrage generiert wurde:Here is one possible parallel plan generated for the query previously shown:

|--Stream Aggregate(GROUP BY:([ORDERS].[o_orderpriority])
                  DEFINE:([Expr1005]=COUNT(*)))
    |--Parallelism(Gather Streams, ORDER BY:
                  ([ORDERS].[o_orderpriority] ASC))
         |--Stream Aggregate(GROUP BY:
                  ([ORDERS].[o_orderpriority])
                  DEFINE:([Expr1005]=Count(*)))
              |--Sort(ORDER BY:([ORDERS].[o_orderpriority] ASC))
                   |--Merge Join(Left Semi Join, MERGE:
                  ([ORDERS].[o_orderkey])=
                        ([LINEITEM].[l_orderkey]),
                  RESIDUAL:([ORDERS].[o_orderkey]=
                        [LINEITEM].[l_orderkey]))
                        |--Sort(ORDER BY:([ORDERS].[o_orderkey] ASC))
                        |    |--Parallelism(Repartition Streams,
                           PARTITION COLUMNS:
                           ([ORDERS].[o_orderkey]))
                        |         |--Index Seek(OBJECT:
                     ([tpcd1G].[dbo].[ORDERS].[O_DATKEYOPR_IDX]),
                     SEEK:([ORDERS].[o_orderdate] >=
                           Apr  1 2000 12:00AM AND
                           [ORDERS].[o_orderdate] <
                           Jul  1 2000 12:00AM) ORDERED)
                        |--Parallelism(Repartition Streams,
                     PARTITION COLUMNS:
                     ([LINEITEM].[l_orderkey]),
                     ORDER BY:([LINEITEM].[l_orderkey] ASC))
                             |--Filter(WHERE:
                           ([LINEITEM].[l_commitdate]<
                           [LINEITEM].[l_receiptdate]))
                                  |--Index Scan(OBJECT:
         ([tpcd1G].[dbo].[LINEITEM].[L_ORDER_DATES_IDX]), ORDERED)

Die folgende Abbildung zeigt einen Abfrageplan, der mit einem Parallelitätsgrad von 4 ausgeführt wird und ein Join von zwei Tabellen einschließt.The illustration below shows a query plan executed with a degree of parallelism equal to 4 and involving a two-table join.

parallel_plan

Der parallele Plan enthält drei Parallelism-Operatoren.The parallel plan contains three parallelism operators. Sowohl der „Index Seek“-Operator des o_datkey_ptr-Indexes als auch der „Index Scan“-Operator des l_order_dates_idx-Indexes werden parallel ausgeführt.Both the Index Seek operator of the o_datkey_ptr index and the Index Scan operator of the l_order_dates_idx index are performed in parallel. Dadurch werden mehrere exklusive Datenströme erzeugt.This produces several exclusive streams. Dies kann mithilfe der nächsten Parallelism-Operatoren oberhalb der Operatoren „Index Scan“ und „Index Seek“ bestimmt werden.This can be determined from the nearest Parallelism operators above the Index Scan and Index Seek operators, respectively. Beide Operatoren nehmen einfach eine Umverteilung der Daten auf die Datenströme vor,Both are repartitioning the type of exchange. sodass dieselbe Anzahl von Datenströmen als Ausgabe erzeugt wird, wie als Eingabe vorlag.That is, they are just reshuffling data among the streams and producing the same number of streams on their output as they have on their input. Diese Anzahl der Datenströme entspricht dem Grad an Parallelität.This number of streams is equal to the degree of parallelism.

Der „Parallelism“-Operator oberhalb des l_order_dates_idx Index Scan-Operators nimmt mithilfe des Werts für L_ORDERKEY als Schlüssel eine Neueinteilung der Eingabedatenströme vor.The parallelism operator above the l_order_dates_idx Index Scan operator is repartitioning its input streams using the value of L_ORDERKEY as a key. Auf diese Weise gelangen identische Werte für L_ORDERKEY in dieselben Ausgabedatenströme.In this way, the same values of L_ORDERKEY end up in the same output stream. Gleichzeitig behalten die Ausgabedatenströme die Reihenfolge für die L_ORDERKEY-Spalte bei, sodass die Eingabeanforderungen des „Merge Join“-Operators erfüllt sind.At the same time, output streams maintain the order on the L_ORDERKEY column to meet the input requirement of the Merge Join operator.

Der „Parallelism“-Operator oberhalb des „Index Seek“-Operators nimmt mithilfe des Werts für O_ORDERKEY eine Neueinteilung der Eingabedatenströme vor.The parallelism operator above the Index Seek operator is repartitioning its input streams using the value of O_ORDERKEY. Da die Eingabe nicht anhand der Werte der O_ORDERKEY-Spalte sortiert wird, es sich hierbei aber um die Joinspalte des Merge Join-Operators handelt, stellt der „Sort“-Operator zwischen dem „Parallelism“- und dem „Merge Join“-Operator sicher, dass die Eingabe für den Merge Join-Operator auf der Basis der Joinspalten sortiert wird.Because its input is not sorted on the O_ORDERKEY column values and this is the join column in the Merge Join operator, the Sort operator between the parallelism and Merge Join operators make sure that the input is sorted for the Merge Join operator on the join columns. Der Sort-Operator wird wie der „Merge Join“-Operator parallel ausgeführt.The Sort operator, like the Merge Join operator, is performed in parallel.

Der oberste „Parallelism“-Operator fasst die Ergebnisse von mehreren Datenströmen in einem einzigen Datenstrom zusammen.The topmost parallelism operator gathers results from several streams into a single stream. Teilaggregationen, die vom „Stream Aggregate“-Operator unterhalb des „Parallelism“-Operators vorgenommen werden, werden dann in dem „Stream Aggregate“-Operator oberhalb des „Parallelism“-Operators zu einem einzigen SUM-Wert für jeden Wert von O_ORDERPRIORITY aufsummiert.Partial aggregations performed by the Stream Aggregate operator below the parallelism operator are then accumulated into a single SUM value for each different value of the O_ORDERPRIORITY in the Stream Aggregate operator above the parallelism operator. Dieser Plan verwendet acht Arbeisthreads, da er zwei Austauschsegmente mit einem Parallelitätsgrad von 4 besitzt.Because this plan has two exchange segments, with degree of parallelism equal to 4, it uses eight worker threads.

Weitere Informationen zu den in diesem Beispiel verwendeten Operatoren finden Sie unter Showplan Logical and Physical Operators Reference (Referenz zu logischen und physischen Showplanoperatoren).For more information on the operators used in this example, refer to the Showplan Logical and Physical Operators Reference.

Parallele IndexvorgängeParallel Index Operations

Die für das Erstellen oder Neuerstellen eines Indexes bzw. für das Löschen eines gruppierten Indexes erstellten Abfragepläne ermöglichen parallele Threadvorgänge mit mehreren Workern auf Computern, die über mehrere Mikroprozessoren verfügen.The query plans built for the index operations that create or rebuild an index, or drop a clustered index, allow for parallel, multi-worker threaded operations on computers that have multiple microprocessors.

Hinweis

Parallele Indexvorgänge sind nur in Enterprise Edition ab SQL Server 2008SQL Server 2008 verfügbar.Parallel index operations are only available in Enterprise Edition, starting with SQL Server 2008SQL Server 2008.

SQL ServerSQL Server verwendet die gleichen Algorithmen wie bei anderen Abfragen, um den Grad an Parallelität (die Gesamtzahl der separaten Arbeitsthreads, die ausgeführt werden sollen) für Indexvorgänge zu ermitteln.uses the same algorithms to determine the degree of parallelism (the total number of separate worker threads to run) for index operations as it does for other queries. Der maximale Grad an Parallelität für einen Indexvorgang hängt von der Serverkonfigurationsoption Max. Grad an Parallelität ab.The maximum degree of parallelism for an index operation is subject to the max degree of parallelism server configuration option. Der Wert „Max. Grad an Parallelität“ kann für einzelne Indexvorgänge überschrieben werden; legen Sie hierzu die MAXDOP-Indexoption in den Anweisungen CREATE INDEX, ALTER INDEX, DROP INDEX und ALTER TABLE fest.You can override the max degree of parallelism value for individual index operations by setting the MAXDOP index option in the CREATE INDEX, ALTER INDEX, DROP INDEX, and ALTER TABLE statements.

Wenn SQL Server-Datenbank-EngineSQL Server Database Engine einen Indexausführungsplan erstellt, wird die Anzahl der parallelen Vorgänge auf den niedrigsten der folgenden Werte festgelegt:When the SQL Server-Datenbank-EngineSQL Server Database Engine builds an index execution plan, the number of parallel operations is set to the lowest value from among the following:

  • Die Anzahl der Mikroprozessoren (oder CPUs) des Computers.The number of microprocessors, or CPUs in the computer.
  • Die in der Serverkonfigurationsoption „Max. Grad an Parallelität“ angegebene Anzahl.The number specified in the max degree of parallelism server configuration option.
  • Die Anzahl der CPUs, die nicht bereits einen Schwellenwert an Arbeit überschritten haben, die für SQL ServerSQL Server-Arbeitsthreads durchgeführt wird.The number of CPUs not already over a threshold of work performed for SQL ServerSQL Server worker threads.

Auf einem Computer mit acht CPUs und einem Wert für „Max. Grad an Parallelität“ in Höhe von 6 werden z.B. maximal sechs parallele Arbeitsthreads für einen Indexvorgang generiert.For example, on a computer that has eight CPUs, but where max degree of parallelism is set to 6, no more than six parallel worker threads are generated for an index operation. Falls fünf der CPUs in dem Computer bereits den Schwellenwert von SQL ServerSQL Server-Arbeit überschritten haben, wenn ein Indexausführungsplan erstellt wird, legt der Ausführungsplan nur drei parallele Arbeitsthreads fest.If five of the CPUs in the computer exceed the threshold of SQL ServerSQL Server work when an index execution plan is built, the execution plan specifies only three parallel worker threads.

Die Hauptphasen eines parallelen Indexvorgangs umfassen Folgendes:The main phases of a parallel index operation include the following:

  • Ein koordinierender Arbeitsthread scannt die Tabelle schnell und nach dem Zufallsprinzip, um die Verteilung der Indexschlüssel einzuschätzen.A coordinating worker thread quickly and randomly scans the table to estimate the distribution of the index keys. Der koordinierende Arbeitsthread legt die Schlüsselgrenzen fest, die eine Reihe von Schlüsselbereichen erstellen, die dem Grad an parallelen Vorgängen entsprechen, wobei jeder Schlüsselbereich so geschätzt wird, dass eine ähnlich große Anzahl von Zeilen abgedeckt ist.The coordinating worker thread establishes the key boundaries that will create a number of key ranges equal to the degree of parallel operations, where each key range is estimated to cover similar numbers of rows. Wenn z.B. vier Millionen Zeilen in einer Tabelle vorhanden sind und der Grad an Parallelität 4 beträgt, bestimmt der koordinierende Arbeitsthread die Schlüsselwerte, die vier Zeilengruppen mit je einer Million Zeilen in jeder Gruppe trennen.For example, if there are four million rows in the table and the degree of parallelism is 4, the coordinating worker thread will determine the key values that delimit four sets of rows with 1 million rows in each set. Wenn nicht genügend Schlüsselbereiche für die Verwendung aller CPUs eingerichtet werden können, wird der Grad an Parallelität entsprechend verringert.If enough key ranges cannot be established to use all CPUs, the degree of parallelism is reduced accordingly.
  • Der koordinierende Arbeitsthread verteilt eine Reihe von Arbeitsthreads, die dem Grad an parallelen Vorgängen entsprechen, und wartet, dass diese Arbeitsthreads ihre Arbeit beenden.The coordinating worker thread dispatches a number of worker threads equal to the degree of parallel operations and waits for these worker threads to complete their work. Jeder Arbeitsthread scannt die Basistabelle mithilfe eines Filters, der nur Zeilen mit Schlüsselwerten in dem Bereich abruft, der dem Arbeitsthread zugewiesen ist.Each worker thread scans the base table using a filter that retrieves only rows with key values within the range assigned to the worker thread. Jeder Arbeitsthread erstellt eine Indexstruktur für die Zeilen in seinem Schlüsselbereich.Each worker thread builds an index structure for the rows in its key range. Bei einem partitionierten Index erstellt jeder Arbeitsthread eine angegebene Anzahl an Partitionen.In the case of a partitioned index, each worker thread builds a specified number of partitions. Partitionen werden nicht für Arbeitsthreads freigegeben.Partitions are not shared among worker threads.
  • Nachdem alle parallelen Arbeitsthreads abgeschlossen sind, verbindet der koordinierende Arbeitsthread die Untereinheiten des Indexes zu einem einzelnen Index.After all the parallel worker threads have completed, the coordinating worker thread connects the index subunits into a single index. Diese Phase gilt nur für Offline-Indexvorgänge.This phase applies only to offline index operations.

Einzelne CREATE TABLE - oder ALTER TABLE -Anweisungen können über mehrere Einschränkungen verfügen, die die Erstellung eines Indexes erforderlich machen.Individual CREATE TABLE or ALTER TABLE statements can have multiple constraints that require that an index be created. Diese mehrfachen Indexerstellungsvorgänge werden seriell durchgeführt, obwohl jeder einzelne Indexerstellungsvorgang auf einem Computer mit mehreren CPUs als paralleler Vorgang ausgeführt werden kann.These multiple index creation operations are performed in series, although each individual index creation operation may be a parallel operation on a computer that has multiple CPUs.

Architektur verteilter AbfragenDistributed Query Architecture

Microsoft SQL ServerSQL Server unterstützt zwei Methoden, um auf heterogene OLE DB-Datenquellen in Transact-SQLTransact-SQL-Anweisungen zu verweisen:Microsoft SQL ServerSQL Server supports two methods for referencing heterogeneous OLE DB data sources in Transact-SQLTransact-SQL statements:

  • VerbindungsservernamenLinked server names
    Mithilfe der gespeicherten Systemprozeduren sp_addlinkedserver und sp_addlinkedsrvlogin kann einer OLE DB-Datenquelle ein Servername zugewiesen werden.The system stored procedures sp_addlinkedserver and sp_addlinkedsrvlogin are used to give a server name to an OLE DB data source. Auf Objekte in diesen Verbindungsservern kann in Transact-SQLTransact-SQL-Anweisungen mithilfe von aus vier Teilen bestehenden Namen verwiesen werden.Objects in these linked servers can be referenced in Transact-SQLTransact-SQL statements using four-part names. Wenn z.B. der Verbindungsservername DeptSQLSrvr für eine andere Instanz von SQL ServerSQL Server definiert wird, verweist die folgende Anweisung auf eine Tabelle auf diesem Server:For example, if a linked server name of DeptSQLSrvr is defined against another instance of SQL ServerSQL Server, the following statement references a table on that server:

    SELECT JobTitle, HireDate 
    FROM DeptSQLSrvr.AdventureWorks2014.HumanResources.Employee;
    

    Der Verbindungsservername kann auch in einer OPENQUERY -Anweisung angegeben werden, um ein Rowset aus einer OLE DB-Datenquelle zu öffnen.The linked server name can also be specified in an OPENQUERY statement to open a rowset from the OLE DB data source. In Transact-SQLTransact-SQL-Anweisungen kann dann auf dieses Rowset wie auf eine Tabelle verwiesen werden.This rowset can then be referenced like a table in Transact-SQLTransact-SQL statements.

  • Ad-hoc-KonnektornamenAd hoc connector names
    Für seltene Verweise auf eine Datenquelle wird die OPENROWSET - oder OPENDATASOURCE -Funktion zusammen mit den Informationen angegeben, die zum Herstellen einer Verbindung mit dem Verbindungsserver erforderlich sind.For infrequent references to a data source, the OPENROWSET or OPENDATASOURCE functions are specified with the information needed to connect to the linked server. Auf das Rowset kann dann auf die gleiche Weise verwiesen werden, wie auf eine Tabelle in Transact-SQLTransact-SQL-Anweisungen verwiesen wird:The rowset can then be referenced the same way a table is referenced in Transact-SQLTransact-SQL statements:

    SELECT *
    FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0',
          'c:\MSOffice\Access\Samples\Northwind.mdb';'Admin';'';
          Employees);
    

SQL ServerSQL Server verwendet OLE DB für die Kommunikation zwischen der relationalen Engine und der Speicher-Engine.uses OLE DB to communicate between the relational engine and the storage engine. Die relationale Engine zerlegt jede Transact-SQLTransact-SQL-Anweisung in eine Reihe von Vorgängen für einfache OLE DB-Rowsets, die durch die Speicher-Engine aus den Basistabellen geöffnet werden.The relational engine breaks down each Transact-SQLTransact-SQL statement into a series of operations on simple OLE DB rowsets opened by the storage engine from the base tables. Dies bedeutet, dass die relationale Engine einfache OLE DB-Rowsets auch für jede OLE DB-Datenquelle öffnen kann.This means the relational engine can also open simple OLE DB rowsets on any OLE DB data source.
oledb_storageoledb_storage
Die relationale Engine verwendet die OLE DB-API (Application Programming Interface), um die Rowsets auf Verbindungsservern zu öffnen, die Zeilen abzurufen und Transaktionen zu verwalten.The relational engine uses the OLE DB application programming interface (API) to open the rowsets on linked servers, fetch the rows, and manage transactions.

Auf dem Server, auf dem SQL ServerSQL Server ausgeführt wird, muss für jede OLE DB-Datenquelle, auf die als Verbindungsserver zugegriffen wird, ein OLE DB-Anbieter vorhanden sein.For each OLE DB data source accessed as a linked server, an OLE DB provider must be present on the server running SQL ServerSQL Server. Der Reihe von Transact-SQLTransact-SQL-Vorgängen, die für eine bestimmte OLE DB-Datenquelle angewendet werden können, wird durch die Funktionalität des OLE DB-Anbieters bestimmt.The set of Transact-SQLTransact-SQL operations that can be used against a specific OLE DB data source depends on the capabilities of the OLE DB provider.

Mitglieder der festen Serverrolle sysadmin können mithilfe der SQL ServerSQL Server-Eigenschaft DisallowAdhocAccess die Ad-hoc-Connectornamen für einen OLE DB-Anbieter in jeder Instanz von SQL ServerSQL Server aktivieren oder deaktivieren.For each instance of SQL ServerSQL Server, members of the sysadmin fixed server role can enable or disable the use of ad-hoc connector names for an OLE DB provider using the SQL ServerSQL ServerDisallowAdhocAccess property. Bei aktiviertem Ad-hoc-Zugriff kann ein beliebiger Benutzer, der bei der Instanz angemeldet ist, Transact-SQLTransact-SQL-Anweisungen mit Ad-hoc-Konnektornamen ausführen, die auf eine beliebige Datenquelle im Netzwerk verweisen, und mithilfe dieses OLE DB-Anbieters auf diese Datenquellen zugreifen.When ad-hoc access is enabled, any user logged on to that instance can execute Transact-SQLTransact-SQL statements containing ad-hoc connector names, referencing any data source on the network that can be accessed using that OLE DB provider. Mitglieder der sysadmin -Rolle können zum Steuern des Zugriffs auf Datenquellen den Ad-hoc-Zugriff auf diesen OLE DB-Anbieter deaktivieren. Auf diese Weise können Benutzer lediglich auf diejenigen Datenquellen zugreifen, auf die mit den von den Administratoren definierten Verbindungsservernamen verwiesen wird.To control access to data sources, members of the sysadmin role can disable ad-hoc access for that OLE DB provider, thereby limiting users to only those data sources referenced by linked server names defined by the administrators. Standardmäßig ist der Ad-hoc-Zugriff für SQL ServerSQL Server-OLE DB-Anbieter aktiviert und für alle anderen OLE DB-Anbieter deaktiviert.By default, ad-hoc access is enabled for the SQL ServerSQL Server OLE DB provider, and disabled for all other OLE DB providers.

Mithilfe von verteilten Abfragen kann Benutzern der Zugriff auf andere Datenquellen gewährt werden (z.B. auf Dateien, nicht relationale Datenquellen wie Active Directory usw.). Dies geschieht innerhalb des Sicherheitskontexts des Microsoft Windows-Kontos, mit dem der SQL ServerSQL Server-Dienst ausgeführt wird.Distributed queries can allow users to access another data source (for example, files, non-relational data sources such as Active Directory, and so on) using the security context of the Microsoft Windows account under which the SQL ServerSQL Server service is running. Bei Windows-Anmeldungen nimmt SQL ServerSQL Server die Identität der Anmeldung ordnungsgemäß an; dies ist jedoch bei SQL ServerSQL Server-Anmeldungen nicht möglich.SQL ServerSQL Server impersonates the login appropriately for Windows logins; however, that is not possible for SQL ServerSQL Server logins. Auf diese Weise ist es einem Benutzer, der verteilte Abfragen ausführt, potenziell möglich, auf eine andere Datenquelle zuzugreifen, für die er selbst keine Berechtigungen hat, wohl aber das Konto, unter dem der SQL ServerSQL Server-Dienst ausgeführt wird.This can potentially allow a distributed query user to access another data source for which they do not have permissions, but the account under which the SQL ServerSQL Server service is running does have permissions. Verwenden Sie sp_addlinkedsrvlogin , um spezifische Anmeldungen mit Zugriffsrechten für die entsprechenden Verbindungsserver zu definieren.Use sp_addlinkedsrvlogin to define the specific logins that are authorized to access the corresponding linked server. Diese Steuerung ist nicht für Ad-hoc-Namen verfügbar. Sie sollten daher sehr sorgfältig beim Aktivieren eines OLE DB-Anbieters für den Ad-hoc-Zugriff sein.This control is not available for ad-hoc names, so use caution in enabling an OLE DB provider for ad-hoc access.

Wenn möglich, verlagert SQL ServerSQL Server relationale Vorgänge wie Joins, Einschränkungen, Projektionen, Sortierungen und Gruppierungen auf die OLE DB-Datenquelle.When possible, SQL ServerSQL Server pushes relational operations such as joins, restrictions, projections, sorts, and group by operations to the OLE DB data source. SQL ServerSQL Server liest die Basistabellen nicht standardmäßig in SQL ServerSQL Server ein, um die relationalen Vorgänge selbst durchzuführen.does not default to scanning the base table into SQL ServerSQL Server and performing the relational operations itself. SQL ServerSQL Server fragt den OLE DB-Anbieter ab, um zu ermitteln, welche Ebene der SQL-Grammatik er unterstützt, und sendet auf der Grundlage dieser Informationen so viele relationale Vorgänge wie möglich an den Anbieter.queries the OLE DB provider to determine the level of SQL grammar it supports, and, based on that information, pushes as many relational operations as possible to the provider.

SQL ServerSQL Server gibt einen Mechanismus an, mit dem ein OLE DB-Anbieter Statistiken zur Verteilung von Schlüsselwerten innerhalb der OLE DB-Datenquelle zurückgibt.specifies a mechanism for an OLE DB provider to return statistics indicating how key values are distributed within the OLE DB data source. So kann der SQL ServerSQL Server-Abfrageoptimierer das Datenmuster in der Datenquelle im Hinblick auf die Anforderungen jeder Transact-SQLTransact-SQL-Anweisung besser analysieren, wodurch der Abfrageoptimierer besser in der Lage ist, optimale Ausführungspläne zu generieren.This lets the SQL ServerSQL Server Query Optimizer better analyze the pattern of data in the data source against the requirements of each Transact-SQLTransact-SQL statement, increasing the ability of the Query Optimizer to generate optimal execution plans.

Verbesserte Abfrageverarbeitung bei partitionierten Tabellen und IndizesQuery Processing Enhancements on Partitioned Tables and Indexes

SQL Server 2008SQL Server 2008 hat für viele parallele Pläne eine bessere Leistung bei der Verarbeitung von Abfragen in partitionierten Tabellen, eine geänderte Art der Darstellung paralleler und serieller Pläne und bessere Partitionierungsinformationen in Kompilierzeit- und Laufzeitausführungsplänen ermöglicht.improved query processing performance on partitioned tables for many parallel plans, changes the way parallel and serial plans are represented, and enhanced the partitioning information provided in both compile-time and run-time execution plans. In diesem Thema werden diese Verbesserungen vorgestellt. Außerdem erhalten Sie Hinweise zur Interpretation der Abfrageausführungspläne für partitionierte Tabellen und Indizes sowie zu bewährten Methoden zur Verbesserung der Abfrageleistung bei partitionierten Objekten.This topic describes these improvements, provides guidance on how to interpret the query execution plans of partitioned tables and indexes, and provides best practices for improving query performance on partitioned objects.

Hinweis

Partitionierte Tabellen und Indizes werden nur in der Enterprise Edition, Developer Edition und Evaluation Edition von SQL ServerSQL Server unterstützt.Partitioned tables and indexes are supported only in the SQL ServerSQL Server Enterprise, Developer, and Evaluation editions.

Neuer partitionsgerichteter Suchvorgang (SEEK)New Partition-Aware Seek Operation

In SQL ServerSQL Server wird die interne Darstellung einer partitionierten Tabelle so geändert, dass der Abfrageprozessor die Tabelle für einen mehrspaltigen Index mit PartitionID als führender Spalte hält.In SQL ServerSQL Server, the internal representation of a partitioned table is changed so that the table appears to the query processor to be a multicolumn index with PartitionID as the leading column. PartitionID ist eine verborgene berechnete Spalte, die intern die ID der Partition, die eine bestimmte Zeile enthält, repräsentiert.is a hidden computed column used internally to represent the ID of the partition containing a specific row. Beispiel: Die Tabelle T, die als T(a, b, c)definiert ist, wird in Spalte a partitioniert und enthält in Spalte b einen gruppierten Index.For example, assume the table T, defined as T(a, b, c), is partitioned on column a, and has a clustered index on column b. In SQL ServerSQL Server wird diese partitionierte Tabelle intern als nicht partitionierte Tabelle mit dem Schema T(PartitionID, a, b, c) und einem gruppierten Index im zusammengesetzten Schlüssel (PartitionID, b) behandelt.In SQL ServerSQL Server, this partitioned table is treated internally as a nonpartitioned table with the schema T(PartitionID, a, b, c) and a clustered index on the composite key (PartitionID, b). Auf diese Weise kann der Abfrageoptimierer Suchvorgänge basierend auf PartitionID in allen partitionierten Tabellen und Indizes durchführen.This allows the Query Optimizer to perform seek operations based on PartitionID on any partitioned table or index.

Die Partitionsentfernung wird jetzt im Suchvorgang vorgenommen.Partition elimination is now done in this seek operation.

In addition, the Query Optimizer is extended so that a seek or scan operation with one condition can be done on PartitionID (als logischer führender Spalte) und ggf. für weitere Indexschlüsselspalten durchgeführt werden kann. Anschließend wird dann für jeden eindeutigen Wert, der die Kriterien des Suchvorgangs der ersten Ebene erfüllt hat, ein Suchvorgang der zweiten Ebene mit einer anderen Bedingung in einer oder mehreren zusätzlichen Spalten durchgeführt.In addition, the Query Optimizer is extended so that a seek or scan operation with one condition can be done on PartitionID (as the logical leading column) and possibly other index key columns, and then a second-level seek, with a different condition, can be done on one or more additional columns, for each distinct value that meets the qualification for the first-level seek operation. Dies bedeutet, dass mit diesem Vorgang, der Skip-Scan genannt wird, der Abfrageoptimierer basierend auf einer Bedingung zunächst einen Such- bzw. Scanvorgang durchführen kann, mit dem die Partitionen ermittelt werden, auf die zugegriffen werden muss, und dann innerhalb dieses Operators einen Indexsuchvorgang der zweiten Ebene, durch den Zeilen in diesen Partitionen zurückgegeben werden, die eine andere Bedingung erfüllen.That is, this operation, called a skip scan, allows the Query Optimizer to perform a seek or scan operation based on one condition to determine the partitions to be accessed and a second-level index seek operation within that operator to return rows from these partitions that meet a different condition. Sehen Sie sich zum Beispiel die folgende Abfrage an:For example, consider the following query.

SELECT * FROM T WHERE a < 10 and b = 2;

Gehen Sie nun davon aus, dass die Tabelle T, die als T(a, b, c)definiert ist, in Spalte a partitioniert wird und in Spalte b einen gruppierten Index enthält.For this example, assume that table T, defined as T(a, b, c), is partitioned on column a, and has a clustered index on column b. Die Partitionsgrenzen für Tabelle T werden mit der folgenden Partitionsfunktion definiert:The partition boundaries for table T are defined by the following partition function:

CREATE PARTITION FUNCTION myRangePF1 (int) AS RANGE LEFT FOR VALUES (3, 7, 10);

Zur Auflösung der Abfrage führt der Abfrageprozessor zunächst einen Suchvorgang der ersten Ebene durch, in dem alle Partitionen mit Zeilen, die die Bedingung T.a < 10erfüllen, gesucht werden.To solve the query, the query processor performs a first-level seek operation to find every partition that contains rows that meet the condition T.a < 10. Hierdurch werden die Partitionen identifiziert, auf die zugegriffen werden muss.This identifies the partitions to be accessed. In diesen identifizierten Partitionen führt der Prozessor dann einen Suchvorgang der zweiten Ebene im gruppierten Index der Spalte b durch, um die Zeilen zu suchen, die die Bedingung T.b = 2 und T.a < 10erfüllen.Within each partition identified, the processor then performs a second-level seek into the clustered index on column b to find the rows that meet the condition T.b = 2 and T.a < 10.

Die folgende Abbildung ist eine logische Darstellung des Skip-Scan-Vorgangs.The following illustration is a logical representation of the skip scan operation. Sie zeigt die Tabelle T mit Daten in den Spalten a und b.It shows table T with data in columns a and b. Die Partitionen sind mit 1 bis 4 nummeriert, wobei die Partitionsgrenzen durch gestrichelte vertikale Linien angezeigt werden.The partitions are numbered 1 through 4 with the partition boundaries shown by dashed vertical lines. Durch einen Suchvorgang der ersten Ebene in den Partitionen (nicht abgebildet) wurde ermittelt, dass die Partitionen 1, 2 und 3 die Suchbedingung, die durch die für die Tabelle definierte Partitionierung und das Prädikat für Spalte a vorgegeben wurde, erfüllen.A first-level seek operation to the partitions (not shown in the illustration) has determined that partitions 1, 2, and 3 meet the seek condition implied by the partitioning defined for the table and the predicate on column a. Das heißt, sie erfüllen die Bedingung T.a < 10.That is, T.a < 10. Der vom Suchvorgang der zweiten Ebene innerhalb des Skip-Scan-Vorgangs durchlaufene Pfad ist anhand der Kurve zu erkennen.The path traversed by the second-level seek portion of the skip scan operation is illustrated by the curved line. Im Wesentlichen wird beim Skip-Scan-Vorgang in diesen Partitionen nach Zeilen gesucht, die die Bedingung b = 2erfüllen.Essentially, the skip scan operation seeks into each of these partitions for rows that meet the condition b = 2. Die Gesamtkosten für den Skip-Scan-Vorgang entsprechen den Kosten, die durch drei separate Indexsuchvorgänge entstehen würden.The total cost of the skip scan operation is the same as that of three separate index seeks.

skip_scan

Anzeigen von Partitionierungsinformationen in AbfrageausführungsplänenDisplaying Partitioning Information in Query Execution Plans

Sie können die Ausführungspläne für Abfragen in partitionierten Tabellen und Indizes überprüfen, indem Sie die SET-Anweisungen von Transact-SQLTransact-SQL, SET SHOWPLAN_XML bzw. SET STATISTICS XML, ausführen oder den in SQL ServerSQL Server Management Studio ausgegebenen grafischen Ausführungsplan verwenden.The execution plans of queries on partitioned tables and indexes can be examined by using the Transact-SQLTransact-SQLSET statements SET SHOWPLAN_XML or SET STATISTICS XML, or by using the graphical execution plan output in SQL ServerSQL Server Management Studio. So können Sie zum Beispiel den Ausführungsplan für die Kompilierzeit anzeigen, indem Sie auf der Abfrage-Editor-Symbolleiste auf Geschätzten Ausführungsplan anzeigen klicken, und den Laufzeitplan, indem Sie auf Tatsächlichen Ausführungsplan einschließenklicken.For example, you can display the compile-time execution plan by clicking Display Estimated Execution Plan on the Query Editor toolbar and the run-time plan by clicking Include Actual Execution Plan.

Mit diesen Tools können Sie die folgenden Informationen abrufen:Using these tools, you can ascertain the following information:

  • Die Vorgänge, wie z.B. scans, seeks, inserts, updates, mergesund deletes , bei denen auf partitionierte Tabellen oder Indizes zugegriffen wird.The operations such as scans, seeks, inserts, updates, merges, and deletes that access partitioned tables or indexes.
  • Die Partitionen, auf die durch die Abfrage zugegriffen wird.The partitions accessed by the query. So finden sich zum Beispiel in Ausführungsplänen für die Laufzeit Informationen zur Gesamtanzahl der Partitionen sowie zu den Bereichen angrenzender Partitionen, auf die zugegriffen wird.For example, the total count of partitions accessed and the ranges of contiguous partitions that are accessed are available in run-time execution plans.
  • Wann Skip-Scan in einem Such- bzw. Scanvorgang verwendet wird, um Daten aus einer oder mehreren Partitionen abzurufen.When the skip scan operation is used in a seek or scan operation to retrieve data from one or more partitions.

Bessere PartitionierungsinformationenPartition Information Enhancements

SQL ServerSQL Server stellt verbesserte Partitionierungsinformationen sowohl für Kompilierzeit- als auch für Laufzeitausführungspläne bereit.provides enhanced partitioning information for both compile-time and run-time execution plans. Die Ausführungspläne enthalten jetzt die folgenden Informationen:Execution plans now provide the following information:

  • Ein optionales Partitioned -Attribut, das anzeigt, dass für eine partitionierte Tabelle ein Operator wie seek, scan, insert, update, mergeoder deleteausgeführt wird.An optional Partitioned attribute that indicates that an operator, such as a seek, scan, insert, update, merge, or delete, is performed on a partitioned table.
  • Ein neues SeekPredicateNew -Element mit einem SeekKeys -Unterelement, das PartitionID als führende Indexschlüsselspalte sowie Filterbedingungen enthält, mit denen Bereichssuchen für PartitionIDfestgelegt werden.A new SeekPredicateNew element with a SeekKeys subelement that includes PartitionID as the leading index key column and filter conditions that specify range seeks on PartitionID. Das Vorhandensein von zwei SeekKeys -Unterelementen zeigt an, dass für PartitionID ein Skip-Scan-Vorgang verwendet wird.The presence of two SeekKeys subelements indicates that a skip scan operation on PartitionID is used.
  • Zusammenfassende Informationen mit der Gesamtanzahl der Partitionen, auf die zugegriffen wird.Summary information that provides a total count of the partitions accessed. Diese Informationen sind nur in Laufzeitplänen verfügbar.This information is available only in run-time plans.

Nehmen Sie die folgende Abfrage für die partitionierte Tabelle fact_salesals Beispiel zur Veranschaulichung, wie diese Informationen im grafischen Ausführungsplan und in der XML-Showplanausgabe angezeigt werden.To demonstrate how this information is displayed in both the graphical execution plan output and the XML Showplan output, consider the following query on the partitioned table fact_sales. Durch diese Abfrage werden Daten in zwei Partitionen aktualisiert.This query updates data in two partitions.

UPDATE fact_sales
SET quantity = quantity * 2
WHERE date_id BETWEEN 20080802 AND 20080902;

Die folgende Abbildung zeigt die Eigenschaften des Clustered Index Seek -Operators im Kompilierzeitausführungsplan für diese Abfrage.The following illustration shows the properties of the Clustered Index Seek operator in the compile-time execution plan for this query. Die Definition der Tabelle fact_sales und die Partitionsdefinition finden Sie in diesem Thema im Abschnitt „Beispiel“.To view the definition of the fact_sales table and the partition definition, see "Example" in this topic.

clustered_index_seek

Das Partitioned-AttributPartitioned Attribute

Wenn ein Operator wie Index Seek für eine partitionierte Tabelle oder einen partitionierten Index ausgeführt wird, enthalten der Kompilierzeit- und der Laufzeitausführungsplan das Attribut Partitioned , das auf True (1) festgelegt wird.When an operator such as an Index Seek is executed on a partitioned table or index, the Partitioned attribute appears in the compile-time and run-time plan and is set to True (1). Das Attribut wird nicht angezeigt, wenn es auf False (0) gesetzt ist.The attribute does not display when it is set to False (0).

Das Partitioned -Attribut kann in den folgenden physischen und logischen Operatoren erscheinen:The Partitioned attribute can appear in the following physical and logical operators:

  • Table Scan
  • Index Scan
  • Index Seek
  • Insert
  • Update
  • Delete
  • Merge

Wie in der obigen Abbildung zu sehen, wird das Attribut in den Eigenschaften des Operators, in dem es definiert ist, angezeigt.As shown in the previous illustration, this attribute is displayed in the properties of the operator in which it is defined. In der XML-Showplanausgabe erscheint das Attribut als Partitioned="1" im RelOp -Knoten des Operators, in dem es definiert ist.In the XML Showplan output, this attribute appears as Partitioned="1" in the RelOp node of the operator in which it is defined.

Neues Suchprädikat (SEEK-Prädikat)New Seek Predicate

In der XML-Showplanausgabe wird das SeekPredicateNew -Element in dem Operator angezeigt, in dem es definiert ist.In XML Showplan output, the SeekPredicateNew element appears in the operator in which it is defined. Das Element kann maximal zwei Instanzen des SeekKeys -Unterelements enthalten.It can contain up to two occurrences of the SeekKeys sub-element. Durch das erste SeekKeys -Element wird der Suchvorgang (SEEK) auf erster Ebene für die Partitions-ID des logischen Index angegeben.The first SeekKeys item specifies the first-level seek operation at the partition ID level of the logical index. In diesem Suchvorgang werden die Partitionen ermittelt, auf die zugegriffen werden muss, damit die Bedingungen der Abfrage erfüllt werden können.That is, this seek determines the partitions that must be accessed to satisfy the conditions of the query. Durch das zweite SeekKeys -Element wird der Suchvorgang auf zweiter Ebene innerhalb des Skip-Scan-Vorgangs festgelegt, der in allen Partitionen durchgeführt wird, die im ersten Suchvorgang identifiziert wurden.The second SeekKeys item specifies the second-level seek portion of the skip scan operation that occurs within each partition identified in the first-level seek.

Zusammenfassende PartitionsinformationenPartition Summary Information

In Laufzeitausführungsplänen geben die zusammenfassenden Partitionsinformationen Auskunft darüber, auf wie viele und auf welche Partitionen zugegriffen wird.In run-time execution plans, partition summary information provides a count of the partitions accessed and the identity of the actual partitions accessed. Anhand dieser Informationen können Sie überprüfen, ob in der Abfrage auf die richtigen Partitionen zugegriffen wird und ob alle anderen Partitionen vom Zugriff ausgenommen werden.You can use this information to verify that the correct partitions are accessed in the query and that all other partitions are eliminated from consideration.

Die folgenden Informationen werden bereitgestellt: Actual Partition Countund Partitions Accessed.The following information is provided: Actual Partition Count, and Partitions Accessed.

Actual Partition Count ist die Gesamtzahl der Partitionen, auf die durch die Abfrage zugegriffen wird.Actual Partition Count is the total number of partitions accessed by the query.

Partitions Accessedist in der XML-Showplanausgabe die Übersichtsinformation zur Partition, die im neuen RuntimePartitionSummary -Element im RelOp -Knoten des Operators, in dem sie definiert ist, erscheint.Partitions Accessed, in XML Showplan output, is the partition summary information that appears in the new RuntimePartitionSummary element in RelOp node of the operator in which it is defined. Das folgende Beispiel zeigt den Inhalt des RuntimePartitionSummary -Elements, durch den angegeben wird, dass auf insgesamt zwei Partitionen (Partition 2 und 3) zugegriffen wird.The following example shows the contents of the RuntimePartitionSummary element, indicating that two total partitions are accessed (partitions 2 and 3).

<RunTimePartitionSummary>

    <PartitionsAccessed PartitionCount="2" >

        <PartitionRange Start="2" End="3" />

    </PartitionsAccessed>

</RunTimePartitionSummary>

Anzeigen von Partitionsinformationen mittels anderer Showplan-MethodenDisplaying Partition Information by Using Other Showplan Methods

Die Showplanmethoden SHOWPLAN_ALL, SHOWPLAN_TEXTund STATISTICS PROFILE stellen keine der in diesem Thema beschriebenen Partitionsinformationen bereit, mit der folgenden Ausnahme.The Showplan methods SHOWPLAN_ALL, SHOWPLAN_TEXT, and STATISTICS PROFILE do not report the partition information described in this topic, with the following exception. Als Teil des SEEK -Prädikats werden die Partitionen, auf die zugegriffen werden muss, durch ein Bereichsprädikat für die berechnete Spalte, die die Partitions-ID repräsentiert, identifiziert.As part of the SEEK predicate, the partitions to be accessed are identified by a range predicate on the computed column representing the partition ID. Das folgende Beispiel zeigt das SEEK -Prädikat für einen Clustered Index Seek -Operator.The following example shows the SEEK predicate for a Clustered Index Seek operator. Es wird auf die Partitionen 2 und 3 zugegriffen, und der SEEK-Operator filtert die Zeilen heraus, die die Bedingung date_id BETWEEN 20080802 AND 20080902erfüllen.Partitions 2 and 3 are accessed, and the seek operator filters on the rows that meet the condition date_id BETWEEN 20080802 AND 20080902.

|--Clustered Index Seek(OBJECT:([db_sales_test].[dbo].[fact_sales].[ci]), 

        SEEK:([PtnId1000] >= (2) AND [PtnId1000] \<= (3) 

                AND [db_sales_test].[dbo].[fact_sales].[date_id] >= (20080802) 

                AND [db_sales_test].[dbo].[fact_sales].[date_id] <= (20080902)) 

                ORDERED FORWARD)

Interpretieren von Ausführungsplänen für partitionierte HeapsInterpreting Execution Plans for Partitioned Heaps

Ein partitionierter Heap wird als logischer Index für die Partitions-ID behandelt.A partitioned heap is treated as a logical index on the partition ID. Die Partitionsentfernung für einen partitionierten Heap wird in einem Ausführungsplan als Table Scan -Operator mit einem SEEK -Prädikat für die Partitions-ID dargestellt.Partition elimination on a partitioned heap is represented in an execution plan as a Table Scan operator with a SEEK predicate on partition ID. Das folgende Beispiel zeigt die bereitgestellten Showplan-Informationen:The following example shows the Showplan information provided:

|-- Table Scan (OBJECT: ([db].[dbo].[T]), SEEK: ([PtnId1001]=[Expr1011]) ORDERED FORWARD)

Interpretieren von Ausführungsplänen für angeordnete JoinsInterpreting Execution Plans for Collocated Joins

Eine Anordnung von Joins kann eintreten, wenn zwei Tabellen mit derselben oder einer ähnlichen Partitionsfunktion partitioniert und die Partitionierungsspalten auf beiden Seiten des Joins in der Join-Bedingung der Abfrage angegeben werden.Join collocation can occur when two tables are partitioned using the same or equivalent partitioning function and the partitioning columns from both sides of the join are specified in the join condition of the query. Der Abfrageoptimierer kann einen Plan erzeugen, in dem die Partitionen aller Tabellen mit identischer Partitions-ID separat verknüpft werden.The Query Optimizer can generate a plan where the partitions of each table that have equal partition IDs are joined separately. Angeordnete Joins sind jedoch möglicherweise schneller als nicht angeordnete, da sie ggf. weniger Arbeitsspeicher und weniger Verarbeitungszeit benötigen.Collocated joins can be faster than non-collocated joins because they can require less memory and processing time. Die Entscheidung, ob ein Plan für nicht angeordnete oder angeordnete Joins erzeugt wird, fällt auf Grundlage der geschätzten Kosten.The Query Optimizer chooses a non-collocated plan or a collocated plan based on cost estimates.

Bei einem Plan für angeordnete Joins liest der Nested Loops -Join eine oder mehrere zusammengefasste Tabellen- oder Indexpartitionen auf der Innenseite.In a collocated plan, the Nested Loops join reads one or more joined table or index partitions from the inner side. Die Zahlen in den Constant Scan -Operatoren repräsentieren die Partitionsnummern.The numbers within the Constant Scan operators represent the partition numbers.

Wenn parallele Pläne für angeordnete Joins für partitionierte Tabellen oder Indizes erzeugt werden, wird ein Parallelism-Operator zwischen dem Constant Scan -Joinoperator und dem Nested Loops -Joinoperator eingefügt.When parallel plans for collocated joins are generated for partitioned tables or indexes, a Parallelism operator appears between the Constant Scan and the Nested Loops join operators. In diesem Fall lesen und bearbeiten mehrere Arbeitsthreads auf der Außenseite des Joins jeweils eine andere Partition.In this case, multiple worker threads on the outer side of the join each read and work on a different partition.

Die folgende Abbildung zeigt einen parallelen Abfrageplan für einen angeordneten Join.The following illustration demonstrates a parallel query plan for a collocated join.
colocated_join

Parallele Ausführungsstrategie für Abfragen bei partitionierten ObjektenParallel Query Execution Strategy for Partitioned Objects

Der Abfrageprozessor verwendet eine parallele Ausführungsstrategie für Abfragen bei partitionierten Objekten.The query processor uses a parallel execution strategy for queries that select from partitioned objects. Im Rahmen dieser Ausführungsstrategie ermittelt der Abfrageprozessor die für die Abfrage erforderlichen Tabellenpartitionen und die den einzelnen Partitionen zugewiesenen Arbeitsthreadanteile.As part of the execution strategy, the query processor determines the table partitions required for the query and the proportion of worker threads to allocate to each partition. In den meisten Fällen ordnet der Abfrageprozessor den einzelnen Partitionen eine etwa gleich große Anzahl an Arbeitsthreads zu und führt anschließend die Abfrage partitionsübergreifend parallel aus.In most cases, the query processor allocates an equal or almost equal number of worker threads to each partition, and then executes the query in parallel across the partitions. In den folgenden Absätzen wird die Arbeitsthreadzuordnung näher erläutert.The following paragraphs explain worker thread allocation in greater detail.

arbeisthread1

Wenn die Arbeitsthreadanzahl kleiner ist als die Partitionsanzahl, ordnet der Abfrageprozessor jeden Arbeitsthread einer anderen Partition zu, und zunächst verbleiben eine oder mehrere Partitionen ohne Arbeitsthreadzuordnung.If the number of worker threads is less than the number of partitions, the query processor assigns each worker thread to a different partition, initially leaving one or more partitions without an assigned worker thread. Wenn die Ausführung eines Arbeitsthreads für eine Partition abgeschlossen ist, weist der Abfrageprozessor diesen der nächsten Partition zu, bis jeder Partition ein Arbeitsthread zugewiesen wurde.When a worker thread finishes executing on a partition, the query processor assigns it to the next partition until each partition has been assigned a single worker thread. Dies ist der einzige Fall, in dem der Abfrageprozessor Arbeitsthreads anderen Partitionen neu zuordnet.This is the only case in which the query processor reallocates worker threads to other partitions.
Zeigt einen Arbeitsthread, der nach seinem Abschluss erneut zugeordnet wurdeShows worker thread reassigned after it finishes. Wenn die Anzahl an Arbeitsthreads und an Partitionen gleich ist, wird jeder Partition ein Arbeitsthread zugewiesen.If the number of worker threads is equal to the number of partitions, the query processor assigns one worker thread to each partition. Abgeschlossene Arbeitsthreads werden nicht erneut zugeordnet.When a worker thread finishes, it is not reallocated to another partition.

arbeitsthread2

Wenn die Arbeitsthreadanzahl größer ist als die Partitionsanzahl, wird jeder Partition dieselbe Anzahl an Arbeitsthreads zugewiesen.If the number of worker threads is greater than the number of partitions, the query processor allocates an equal number of worker threads to each partition. Falls es sich bei der Anzahl an Arbeitsthreads nicht um ein Vielfaches der Anzahl an Partitionen handelt, weist der Abfrageprozessor einigen Partitionen einen weiteren Arbeitsthread zu, sodass alle verfügbaren Arbeitsthreads verwendet werden.If the number of worker threads is not an exact multiple of the number of partitions, the query processor allocates one additional worker thread to some partitions in order to use all of the available worker threads. Wenn nur eine Partition vorhanden ist, werden alle Arbeitsthreads dieser Partition zugewiesen.Note that if there is only one partition, all worker threads will be assigned to that partition. In der Abbildung unten sind vier Partitionen und 14 Arbeitsthreads verfügbar.In the diagram below, there are four partitions and 14 worker threads. Jeder Partition werden drei Arbeitsthreads zugewiesen, und zwei Partitionen wird jeweils ein zusätzlicher Arbeitsthread zugewiesen, sodass alle 14 Arbeitsthreads zugewiesen sind.Each partition has 3 worker threads assigned, and two partitions have an additional worker thread, for a total of 14 worker thread assignments. Abgeschlossene Arbeitsthreads werden nicht erneut zugeordnet.When a worker thread finishes, it is not reassigned to another partition.

arbeitsthread3

Die oben aufgeführten Beispiele sind einfache Beschreibungen der Arbeitsthreadzuordnung. Die tatsächliche Strategie ist komplexer und umfasst weitere Variablen, die sich während der Abfrageausführung ergeben.Although the above examples suggest a straightforward way to allocate worker threads, the actual strategy is more complex and accounts for other variables that occur during query execution. Beispiel: Wenn die Tabelle partitioniert ist, in Spalte A einen gruppierten Index aufweist und eine Abfrage mit der Prädikatklausel WHERE A IN (13, 17, 25)verwendet wird, weist der Abfrageprozessor jedem dieser drei Suchwerte (A=13, A=17 und A=25) statt jeder Tabellenpartition einen oder mehrere Arbeitsthreads zu.For example, if the table is partitioned and has a clustered index on column A and a query has the predicate clause WHERE A IN (13, 17, 25), the query processor will allocate one or more worker threads to each of these three seek values (A=13, A=17, and A=25) instead of each table partition. Die Abfrage muss nur für die Partitionen ausgeführt werden, die diese Werte enthalten. Wenn sich alle Suchwerte in derselben Partition befinden, werden alle Arbeitsthreads dieser Partition zugewiesen.It is only necessary to execute the query in the partitions that contain these values, and if all of these seek predicates happen to be in the same table partition, all of the worker threads will be assigned to the same table partition.

Ein weiteres Beispiel: Die Tabelle weist vier Partitionen in Spalte A mit Grenzpunkten (10, 20, 30) sowie einen Index in Spalte B auf, und für die Abfrage wird folgende Prädikatklausel verwendet: WHERE B IN (50, 100, 150).To take another example, suppose that the table has four partitions on column A with boundary points (10, 20, 30), an index on column B, and the query has a predicate clause WHERE B IN (50, 100, 150). Da die Tabellenpartitionen auf den A-Werten basieren, können die B-Werte in allen Tabellenpartitionen enthalten sein.Because the table partitions are based on the values of A, the values of B can occur in any of the table partitions. Somit sucht der Abfrageprozessor in jeder der vier Tabellenpartitionen nach jedem der drei B-Werte (50, 100, 150).Thus, the query processor will seek for each of the three values of B (50, 100, 150) in each of the four table partitions. Der Abfrageprozessor weist Arbeitsthreads proportional zu, sodass alle zwölf Abfragesuchläufe parallel ausgeführt werden können.The query processor will assign worker threads proportionately so that it can execute each of these 12 query scans in parallel.

Tabellenpartitionen auf Grundlage der Spalte ATable partitions based on column A Suche in allen Tabellenpartitionen nach B-SpaltenwertenSeeks for column B in each table partition
Tabellenpartition 1: A < 10Table Partition 1: A < 10 B=50, B=100, B=150B=50, B=100, B=150
Tabellenpartition 2: A >= 10 AND A < 20Table Partition 2: A >= 10 AND A < 20 B=50, B=100, B=150B=50, B=100, B=150
Tabellenpartition 3: A >= 20 AND A < 30Table Partition 3: A >= 20 AND A < 30 B=50, B=100, B=150B=50, B=100, B=150
Tabellenpartition 4: A >= 30Table Partition 4: A >= 30 B=50, B=100, B=150B=50, B=100, B=150

Bewährte MethodenBest Practices

Wir empfehlen die folgenden bewährten Vorgehensweisen, um die Leistung von Abfragen zu verbessern, bei denen in großen partitionierten Tabellen und Indizes auf eine große Menge von Daten zugegriffen wird:To improve the performance of queries that access a large amount of data from large partitioned tables and indexes, we recommend the following best practices:

  • Verteilen Sie alle Partitionen über viele Datenträger (Datenträgerstriping).Stripe each partition across many disks. Dies ist besonders bei Verwendung von Festplatten relevant.This is especially relevant when using spinning disks.
  • Verwenden Sie möglichst einen Server mit einem Hauptspeicher, der groß genug ist für Partitionen, auf die häufig zugegriffen wird, bzw. für alle Partitionen, um die E/A-Kosten zu senken.When possible, use a server with enough main memory to fit frequently accessed partitions or all partitions in memory to reduce I/O cost.
  • Falls die abgefragten Daten nicht in den Arbeitsspeicher passen, komprimieren Sie die Tabellen und Indizes.If the data you query will not fit in memory, compress the tables and indexes. Dies reduziert die E/A-Kosten.This will reduce I/O cost.
  • Verwenden Sie einen Server mit schnellen und möglichst vielen Prozessoren, um sich die Vorteile der parallelen Abfrageverarbeitung zu Nutze zu machen.Use a server with fast processors and as many processor cores as you can afford, to take advantage of parallel query processing capability.
  • Stellen Sie sicher, dass der Server über eine ausreichend große E/A-Controllerbandbreite verfügt.Ensure the server has sufficient I/O controller bandwidth.
  • Erstellen Sie für jede große partitionierte Tabelle einen gruppierten Index, um den optimierten B-Strukturscan voll nutzen zu können.Create a clustered index on every large partitioned table to take advantage of B-tree scanning optimizations.
  • Beachten Sie die Empfehlungen für bewährte Vorgehensweisen im Whitepaper The Data Loading Performance Guide (Leistungsleitfaden für das Laden von Daten), wenn Sie mittels Massenladen Daten in partitionierte Tabellen laden.Follow the best practice recommendations in the white paper, The Data Loading Performance Guide, when bulk loading data into partitioned tables.

BeispielExample

Im folgenden Beispiel wird eine Testdatenbank mit einer Tabelle, die sieben Partitionen aufweist, erstellt.The following example creates a test database containing a single table with seven partitions. Verwenden Sie die zuvor in diesem Thema vorgestellten Tools, wenn Sie die Abfragen in diesem Beispiel durchführen, um Partitionierungsinformationen für den Kompilierungszeitplan und den Laufzeitplan anzuzeigen.Use the tools described previously when executing the queries in this example to view partitioning information for both compile-time and run-time plans.

Hinweis

In diesem Beispiel werden über eine Millionen Zeilen in die Tabelle eingefügt.This example inserts more than 1 million rows into the table. Je nach Hardware kann die Ausführung dieses Beispiels einige Minuten dauern.Running this example may take several minutes depending on your hardware. Stellen Sie vor dem Ausführen dieses Beispiels sicher, dass mehr als 1,5 GB Speicherplatz zur Verfügung stehen.Before executing this example, verify that you have more than 1.5 GB of disk space available.

USE master;
GO
IF DB_ID (N'db_sales_test') IS NOT NULL
    DROP DATABASE db_sales_test;
GO
CREATE DATABASE db_sales_test;
GO
USE db_sales_test;
GO
CREATE PARTITION FUNCTION [pf_range_fact](int) AS RANGE RIGHT FOR VALUES 
(20080801, 20080901, 20081001, 20081101, 20081201, 20090101);
GO
CREATE PARTITION SCHEME [ps_fact_sales] AS PARTITION [pf_range_fact] 
ALL TO ([PRIMARY]);
GO
CREATE TABLE fact_sales(date_id int, product_id int, store_id int, 
    quantity int, unit_price numeric(7,2), other_data char(1000))
ON ps_fact_sales(date_id);
GO
CREATE CLUSTERED INDEX ci ON fact_sales(date_id);
GO
PRINT 'Loading...';
SET NOCOUNT ON;
DECLARE @i int;
SET @i = 1;
WHILE (@i<1000000)
BEGIN
    INSERT INTO fact_sales VALUES(20080800 + (@i%30) + 1, @i%10000, @i%200, RAND() * 25, (@i%3) + 1, '');
    SET @i += 1;
END;
GO
DECLARE @i int;
SET @i = 1;
WHILE (@i<10000)
BEGIN
    INSERT INTO fact_sales VALUES(20080900 + (@i%30) + 1, @i%10000, @i%200, RAND() * 25, (@i%3) + 1, '');
    SET @i += 1;
END;
PRINT 'Done.';
GO
-- Two-partition query.
SET STATISTICS XML ON;
GO
SELECT date_id, SUM(quantity*unit_price) AS total_price
FROM fact_sales
WHERE date_id BETWEEN 20080802 AND 20080902
GROUP BY date_id ;
GO
SET STATISTICS XML OFF;
GO
-- Single-partition query.
SET STATISTICS XML ON;
GO
SELECT date_id, SUM(quantity*unit_price) AS total_price
FROM fact_sales
WHERE date_id BETWEEN 20080801 AND 20080831
GROUP BY date_id;
GO
SET STATISTICS XML OFF;
GO

Zusätzliches LesematerialAdditional Reading

Referenz zu logischen und physischen ShowplanoperatorenShowplan Logical and Physical Operators Reference
Erweiterte EreignisseExtended Events
Bewährte Methoden für den Abfragespeicher Best Practice with the Query Store
Kardinalitätsschätzung Cardinality Estimation
Intelligente Abfrageverarbeitung in SQL-Datenbanken Intelligent query processing
Operatorrangfolge Operator precedence
Ausführungspläne Execution Plans
Leistungscenter für SQL Server-Datenbank-Engine und Azure SQL-Datenbank Performance Center for SQL Server Database Engine and Azure SQL Database