Guía del procesamiento de consultas para tablas con optimización para memoriaA Guide to Query Processing for Memory-Optimized Tables

Se aplica a:Applies to: síSQL ServerSQL Server (todas las versiones admitidas) yesSQL ServerSQL Server (all supported versions) SíAzure SQL DatabaseAzure SQL DatabaseYesAzure SQL DatabaseAzure SQL DatabaseSe aplica a:Applies to: síSQL ServerSQL Server (todas las versiones admitidas) yesSQL ServerSQL Server (all supported versions) SíAzure SQL DatabaseAzure SQL DatabaseYesAzure SQL DatabaseAzure SQL Database

OLTP en memoria incluye en SQL ServerSQL Server los procedimientos almacenados compilados de forma nativa y las tablas optimizadas para memoria.In-Memory OLTP introduces memory-optimized tables and natively compiled stored procedures in SQL ServerSQL Server. Este artículo proporciona información general del procesamiento de consultas tanto para las tablas optimizadas para memoria como para los procedimientos almacenados compilados de forma nativa.This article gives an overview of query processing for both memory-optimized tables and natively compiled stored procedures.

En el documento se explica cómo se compilan y ejecutan las consultas en tablas optimizadas para memoria, incluido:The document explains how queries on memory-optimized tables are compiled and executed, including:

  • La canalización de procesamiento de consultas de SQL ServerSQL Server para las tablas basadas en disco.The query processing pipeline in SQL ServerSQL Server for disk-based tables.

  • Optimización de consultas; el rol de las estadísticas en las tablas optimizadas para memoria así como instrucciones para solucionar problemas de planes de consulta no válidos.Query optimization; the role of statistics on memory-optimized tables as well as guidelines for troubleshooting bad query plans.

  • El uso de Transact-SQLTransact-SQL interpretado para tener acceso a tablas optimizadas para memoria.The use of interpreted Transact-SQLTransact-SQL to access memory-optimized tables.

  • Consideraciones sobre la optimización de consultas para el acceso a tablas optimizadas para memoria.Considerations about query optimization for memory-optimized table access.

  • Compilación y procesamiento de procedimientos almacenados de forma nativa.Natively compiled stored procedure compilation and processing.

  • Estadísticas usadas para la estimación del costo por el optimizador.Statistics that are used for cost estimation by the optimizer.

  • Formas de solucionar los planes de consulta no válidos.Ways to fix bad query plans.

Consulta de ejemploExample Query

El ejemplo siguiente se utilizará para mostrar los conceptos del procesamiento de consultas descritos en este artículo.The following example will be used to illustrate the query processing concepts discussed in this article.

Consideramos dos tablas, Customer y Order.We consider two tables, Customer and Order. El siguiente script de Transact-SQLTransact-SQL contiene las definiciones de estas dos tablas y los índices asociados, en su formato basado en disco (tradicional):The following Transact-SQLTransact-SQL script contains the definitions for these two tables and associated indexes, in their (traditional) disk-based form:

CREATE TABLE dbo.[Customer] (  
  CustomerID nchar (5) NOT NULL PRIMARY KEY,  
  ContactName nvarchar (30) NOT NULL   
)  
GO  
  
CREATE TABLE dbo.[Order] (  
  OrderID int NOT NULL PRIMARY KEY,  
  CustomerID nchar (5) NOT NULL,  
  OrderDate date NOT NULL  
)  
GO  
CREATE INDEX IX_CustomerID ON dbo.[Order](CustomerID)  
GO  
CREATE INDEX IX_OrderDate ON dbo.[Order](OrderDate)  
GO  

Para crear los planes de consulta mostrados en este artículo, las dos tablas se rellenaron con datos de ejemplo de la base de datos de ejemplo Northwind, que puede descargar desde Bases de datos de ejemplo Northwind y pubs para SQL Server 2000.For constructing the query plans shown in this article, the two tables were populated with sample data from the Northwind sample database, which you can download from Northwind and pubs Sample Databases for SQL Server 2000.

Considere la siguiente consulta, que combina las tablas Customer y Order y devuelve el identificador del pedido y la información del cliente asociada:Consider the following query, which joins the tables Customer and Order and returns the ID of the order and the associated customer information:

SELECT o.OrderID, c.* FROM dbo.[Customer] c INNER JOIN dbo.[Order] o ON c.CustomerID = o.CustomerID  

El plan de ejecución estimado como se muestra en SQL Server Management StudioSQL Server Management Studio es el siguiente:The estimated execution plan as displayed by SQL Server Management StudioSQL Server Management Studio is as follows

Plan de consulta para una combinación de tablas basadas en disco.Query plan for join of disk-based tables.
Plan de consulta para una combinación de tablas basadas en disco.Query plan for join of disk-based tables.

Acerca de este plan de consulta:About this query plan:

  • Las filas de la tabla Customer se recuperan del índice clúster, que es la estructura de datos principal y tiene los datos completos de la tabla.The rows from the Customer table are retrieved from the clustered index, which is the primary data structure and has the full table data.

  • Los datos de la tabla Order se recuperan usando el índice no agrupado en la columna CustomerID.Data from the Order table is retrieved using the nonclustered index on the CustomerID column. Este índice contiene la columna CustomerID, que se utiliza para la combinación, y la columna de clave principal OrderID, que se devuelve al usuario.This index contains both the CustomerID column, which is used for the join, and the primary key column OrderID, which is returned to the user. Devolver columnas adicionales de la tabla Order requeriría búsquedas en el índice clúster de la tabla Order.Returning additional columns from the Order table would require lookups in the clustered index for the Order table.

  • El operador físico Inner Join implementa el operador lógico Merge Join.The logical operator Inner Join is implemented by the physical operator Merge Join. Los otros tipos de combinación físicos son Nested Loops y Hash Join.The other physical join types are Nested Loops and Hash Join. El operador Merge Join se aprovecha del hecho de que ambos índices están ordenados por la columna de combinación CustomerID.The Merge Join operator takes advantage of the fact that both indexes are sorted on the join column CustomerID.

Considere una ligera variación en esta consulta, que devuelve todas las filas de la tabla Order, no solo OrderID:Consider a slight variation on this query, which returns all rows from the Order table, not only OrderID:

SELECT o.*, c.* FROM dbo.[Customer] c INNER JOIN dbo.[Order] o ON c.CustomerID = o.CustomerID  

El plan estimado de esta consulta es:The estimated plan for this query is:

Plan de consulta para una combinación hash de tablas basadas en disco.Query plan for a hash join of disk-based tables.
Plan de consulta para una combinación hash de tablas basadas en disco.Query plan for a hash join of disk-based tables.

En esta consulta, las filas de la tabla Order se recuperan con el índice clúster.In this query, rows from the Order table are retrieved using the clustered index. Ahora se utiliza el operador físico Hash Match para Inner Join.The Hash Match physical operator is now used for the Inner Join. El índice clúster en la tabla Order no está ordenado en CustomerID y, por lo tanto, Merge Join requeriría un operador de ordenación, lo que afectaría al rendimiento.The clustered index on Order is not sorted on CustomerID, and so a Merge Join would require a sort operator, which would affect performance. Tenga en cuenta el costo relativo del operador Hash Match (75 %) en comparación con el costo del operador Merge Join del ejemplo anterior (46 %).Note the relative cost of the Hash Match operator (75%) compared with the cost of the Merge Join operator in the previous example (46%). El optimizador habría considerado el operador Hash Match también en el ejemplo anterior pero concluyó que el operador Merge Join proporcionaba un rendimiento mejor.The optimizer would have considered the Hash Match operator also in the previous example, but concluded that the Merge Join operator gave better performance.

SQL ServerSQL Server Procesamiento de consultas para las tablas basadas en discoQuery Processing for Disk-Based Tables

El siguiente diagrama muestra el flujo de procesamiento de consultas en SQL ServerSQL Server para las consultas ad hoc:The following diagram outlines the query processing flow in SQL ServerSQL Server for ad hoc queries:

Canalización de procesamiento de consultas de SQL ServerSQL Server query processing pipeline.
Canalización de procesamiento de consultas de SQL ServerSQL Server query processing pipeline.

En este escenario:In this scenario:

  1. El usuario emite una consulta.The user issues a query.

  2. El analizador y el algebrizador construyen un árbol de consulta con operadores lógicos según el texto de Transact-SQLTransact-SQL enviado por el usuario.The parser and algebrizer construct a query tree with logical operators based on the Transact-SQLTransact-SQL text submitted by the user.

  3. El optimizador crea un plan de consulta optimizado que contiene los operadores físicos (por ejemplo, la combinación de bucles anidados).The optimizer creates an optimized query plan containing physical operators (for example, nested-loops join). Después de la optimización, el plan se puede almacenar en la memoria caché de planes.After optimization, the plan may be stored in the plan cache. Se omite este paso si la memoria caché de planes ya contiene un plan para esta consulta.This step is bypassed if the plan cache already contains a plan for this query.

  4. El motor de ejecución de consultas procesa una interpretación del plan de consulta.The query execution engine processes an interpretation of the query plan.

  5. Para cada operador de recorrido de tabla, búsqueda de índice y recorrido de índice, el motor de ejecución solicita las filas de las estructuras respectivas de índice y tabla de Access Methods.For each index seek, index scan, and table scan operator, the execution engine requests rows from the respective index and table structures from Access Methods.

  6. Access Methods recupera las filas de las páginas de datos e índices del grupo de búferes y carga las páginas del disco al grupo de búferes según sea necesario.Access Methods retrieves the rows from the index and data pages in the buffer pool and loads pages from disk into the buffer pool as needed.

Para la primera consulta del ejemplo, el motor de ejecución solicita filas del índice agrupado en la tabla Customer y el índice no agrupado en la tabla Order de Access Methods.For the first example query, the execution engine requests rows in the clustered index on Customer and the nonclustered index on Order from Access Methods. Access Methods atraviesa las estructuras de índice del árbol B para recuperar las filas solicitadas.Access Methods traverses the B-tree index structures to retrieve the requested rows. En este caso, todas las filas se recuperan como las llamadas de plan para los recorridos de índice completos.In this case all rows are retrieved as the plan calls for full index scans.

Acceso de Transact-SQLTransact-SQL interpretado a las tablas con optimización para memoriaInterpreted Transact-SQLTransact-SQL Access to Memory-Optimized Tables

Transact-SQLTransact-SQL también se denominan Transact-SQLTransact-SQL.ad hoc batches and stored procedures are also referred to as interpreted Transact-SQLTransact-SQL. Interpretado hace referencia al hecho de que el plan de consulta es interpretado por el motor de ejecución de consulta para cada operador del plan de consultas.Interpreted refers to the fact that the query plan is interpreted by the query execution engine for each operator in the query plan. El motor de ejecución lee el operador y sus parámetros y realiza la operación.The execution engine reads the operator and its parameters and performs the operation.

Transact-SQLTransact-SQL interpretado se puede utilizar para tener acceso a tablas optimizadas para memoria y a tablas basadas en disco.Interpreted Transact-SQLTransact-SQL can be used to access both memory-optimized and disk-based tables. La ilustración siguiente muestra el procesamiento de consultas para el acceso de Transact-SQLTransact-SQL interpretado a las tablas optimizadas para memoria:The following figure illustrates query processing for interpreted Transact-SQLTransact-SQL access to memory-optimized tables:

Canalización de procesamiento de consulta para tsql interpretado.Query processing pipeline for interpreted tsql.
Canalización de procesamiento de consultas para acceso de Transact-SQL interpretado a tablas optimizadas para memoria.Query processing pipeline for interpreted Transact-SQL access to memory-optimized tables.

Como se muestra en la ilustración, la canalización del procesamiento de consultas permanece principalmente sin cambios:As illustrated by the figure, the query processing pipeline remains mostly unchanged:

  • El analizador y el algebrizador construyen el árbol de consulta.The parser and algebrizer construct the query tree.

  • El optimizador crea el plan de ejecución.The optimizer creates the execution plan.

  • El motor de ejecución de consultas interpreta el plan de ejecución.The query execution engine interprets the execution plan.

La diferencia principal con la canalización de procesamiento de consultas tradicional (la ilustración 2) es que las filas de las tablas optimizadas para memoria no se recuperan del grupo de búferes mediante Access Methods.The main difference with the traditional query processing pipeline (figure 2) is that rows for memory-optimized tables are not retrieved from the buffer pool using Access Methods. En su lugar, las filas se recuperan de las estructuras de datos en memoria a través del motor OLTP en memoria.Instead, rows are retrieved from the in-memory data structures through the In-Memory OLTP engine. Las diferencias en las estructuras de datos hacen que el optimizador elija distintos planes en algunos casos, como se muestra en el ejemplo siguiente.Differences in data structures cause the optimizer to pick different plans in some cases, as illustrated by the following example.

El siguiente script de Transact-SQLTransact-SQL contiene las versiones optimizadas para memoria de las tablas Order y Customer, con índices hash:The following Transact-SQLTransact-SQL script contains memory-optimized versions of the Order and Customer tables, using hash indexes:

CREATE TABLE dbo.[Customer] (  
  CustomerID nchar (5) NOT NULL PRIMARY KEY NONCLUSTERED,  
  ContactName nvarchar (30) NOT NULL   
) WITH (MEMORY_OPTIMIZED=ON)  
GO  
  
CREATE TABLE dbo.[Order] (  
  OrderID int NOT NULL PRIMARY KEY NONCLUSTERED,  
  CustomerID nchar (5) NOT NULL INDEX IX_CustomerID HASH(CustomerID) WITH (BUCKET_COUNT=100000),  
  OrderDate date NOT NULL INDEX IX_OrderDate HASH(OrderDate) WITH (BUCKET_COUNT=100000)  
) WITH (MEMORY_OPTIMIZED=ON)  
GO  

Considere la misma consulta ejecutada en tablas optimizadas para memoria:Consider the same query executed on memory-optimized tables:

SELECT o.OrderID, c.* FROM dbo.[Customer] c INNER JOIN dbo.[Order] o ON c.CustomerID = o.CustomerID  

El plan estimado es el siguiente:The estimated plan is as follows:

Plan de consulta para una combinación de tablas con optimización para memoria.Query plan for join of memory optimized tables.
Plan de consulta para una combinación de tablas optimizadas para memoria.Query plan for join of memory-optimized tables.

Observe las siguientes diferencias con el plan para la misma consulta en las tablas basadas en disco (ilustración 1):Observe the following differences with the plan for the same query on disk-based tables (figure 1):

  • Este plan contiene un recorrido de tabla en lugar de un recorrido de índice clúster para la tabla Customer:This plan contains a table scan rather than a clustered index scan for the table Customer:

    • La definición de la tabla no contiene un índice clúster.The definition of the table does not contain a clustered index.

    • Los índices clúster no se admiten con tablas optimizadas para memoria.Clustered indexes are not supported with memory-optimized tables. En su lugar, cada tabla optimizada para memoria debe tener al menos un índice no clúster y todos los índices de las tablas optimizadas para memoria pueden tener acceso eficazmente a todas las columnas de la tabla sin tener que almacenarlas en el índice o hacer referencia a un índice clúster.Instead, every memory-optimized table must have at least one nonclustered index and all indexes on memory-optimized tables can efficiently access all columns in the table without having to store them in the index or refer to a clustered index.

  • Este plan contiene una Hash Match en lugar de una Merge Join.This plan contains a Hash Match rather than a Merge Join. Los índices en las tablas Order y Customer son índices hash y, por tanto, no se ordenan.The indexes on both the Order and the Customer table are hash indexes, and are thus not ordered. Una Merge Join requeriría operadores de ordenación que reducirían el rendimiento.A Merge Join would require sort operators that would decrease performance.

procedimientos almacenados compilados de forma nativaNatively Compiled Stored Procedures

Los procedimientos almacenados compilados de forma nativa son procedimientos almacenados de Transact-SQLTransact-SQL compilados con código máquina, en lugar de interpretados por el motor de ejecución de consultas.Natively compiled stored procedures are Transact-SQLTransact-SQL stored procedures compiled to machine code, rather than interpreted by the query execution engine. El siguiente script crea un procedimiento almacenado compilado de forma nativa que ejecuta la consulta de ejemplo (de la sección Consulta de ejemplo).The following script creates a natively compiled stored procedure that runs the example query (from the Example Query section).

CREATE PROCEDURE usp_SampleJoin  
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER  
AS BEGIN ATOMIC WITH   
(  TRANSACTION ISOLATION LEVEL = SNAPSHOT,  
  LANGUAGE = 'english')  
  
  SELECT o.OrderID, c.CustomerID, c.ContactName   
FROM dbo.[Order] o INNER JOIN dbo.[Customer] c   
  ON c.CustomerID = o.CustomerID  
  
END  

Los procedimientos almacenados compilados de forma nativa se compilan en el momento de su creación, mientras que los procedimientos almacenados interpretados se compilan la primera vez que se ejecutan.Natively compiled stored procedures are compiled at create time, whereas interpreted stored procedures are compiled at first execution time. (Una parte de la compilación, en particular el análisis y la algebrización, tienen lugar en la creación.(A portion of the compilation, particularly parsing and algebrization, take place at create. Sin embargo, para los procedimientos almacenados interpretados, la optimización de los planes de consulta tiene lugar en la primera ejecución). La lógica de la recompilación es similar.However, for interpreted stored procedures, optimization of the query plans takes place at first execution.) The recompilation logic is similar. Los procedimientos almacenados compilados de forma nativa se recompilan en la primera ejecución del procedimiento si el servidor se reinicia.Natively compiled stored procedures are recompiled on first execution of the procedure if the server is restarted. Los procedimientos almacenados interpretados se recompilan si el plan ya no está en la memoria caché de planes.Interpreted stored procedures are recompiled if the plan is no longer in the plan cache. En la tabla siguiente se resumen los casos de compilación y de recompilación tanto para los procedimientos almacenados interpretados como para los compilados de forma nativa:The following table summarizes compilation and recompilation cases for both natively compiled and interpreted stored procedures:

Tipo de compilaciónCompilation type Compilado de forma nativaNatively compiled Acceso deInterpreted
Compilación inicialInitial compilation En el momento de la creación.At create time. En la primera ejecución.At first execution.
Recompilación automáticaAutomatic recompilation En la primera ejecución del procedimiento después del reinicio de la base de datos o del servidor.Upon first execution of the procedure after a database or server restart. Al reiniciar el servidor.On server restart. O bien, se expulsa de la memoria caché de planes, generalmente según los cambios de esquema o de estadísticas, o por presión en la memoria.Or, eviction from the plan cache, usually based on schema or stats changes, or memory pressure.
Recompilación manualManual recompilation Use sp_recompile.Use sp_recompile. Use sp_recompile.Use sp_recompile. Puede expulsar manualmente el plan de la memoria caché, por ejemplo con DBCC FREEPROCCACHE.You can manually evict the plan from the cache, for example through DBCC FREEPROCCACHE. También puede crear el procedimiento almacenado WITH RECOMPILE y el procedimiento almacenado se recompilará en cada ejecución.You can also create the stored procedure WITH RECOMPILE and the stored procedure will be recompiled at every execution.

Compilación y procesamiento de consultasCompilation and Query Processing

El siguiente diagrama muestra el proceso de compilación para los procedimientos almacenados compilados de forma nativa:The following diagram illustrates the compilation process for natively compiled stored procedures:

Compilación nativa de procedimientos almacenados.Native compilation of stored procedures.
Compilación nativa de procedimientos almacenados.Native compilation of stored procedures.

El proceso se describe comoThe process is described as,

  1. El usuario emite una instrucción CREATE PROCEDURE para SQL ServerSQL Server.The user issues a CREATE PROCEDURE statement to SQL ServerSQL Server.

  2. El analizador y el algebrizador crean el flujo de procesamiento del procedimiento, así como los árboles de consulta para las consultas de Transact-SQLTransact-SQL del procedimiento almacenado.The parser and algebrizer create the processing flow for the procedure, as well as query trees for the Transact-SQLTransact-SQL queries in the stored procedure.

  3. El optimizador crea planes optimizados de ejecución de consultas para todas las consultas en el procedimiento almacenado.The optimizer creates optimized query execution plans for all the queries in the stored procedure.

  4. El compilador OLTP en memoria toma el flujo de procesamiento con los planes de consulta optimizados incrustados y genera un archivo DLL que contiene el código máquina para ejecutar el procedimiento almacenado.The In-Memory OLTP compiler takes the processing flow with the embedded optimized query plans and generates a DLL that contains the machine code for executing the stored procedure.

  5. El archivo DLL generado se carga en memoria.The generated DLL is loaded into memory.

La invocación de un procedimiento almacenado compilado de forma nativa se traduce en la llamada a una función del archivo DLL.Invocation of a natively compiled stored procedure translates to calling a function in the DLL.

Ejecución de los procedimientos almacenados compilados de forma nativa.Execution of natively compiled stored procedures.
Ejecución de los procedimientos almacenados compilados de forma nativa.Execution of natively compiled stored procedures.

La invocación de un procedimiento almacenado compilado de forma nativa se describe como sigue:Invocation of a natively compiled stored procedure is described as follows:

  1. El usuario emite una instrucción EXEC usp_myproc.The user issues an EXEC usp_myproc statement.

  2. El analizador extrae los parámetros del nombre y del procedimiento almacenado.The parser extracts the name and stored procedure parameters.

    Si la instrucción se preparó, por ejemplo con sp_prep_exec, el analizador no necesita extraer el nombre y los parámetros de los procedimientos en tiempo de ejecución.If the statement was prepared, for example using sp_prep_exec, the parser does not need to extract the procedure name and parameters at execution time.

  3. El runtime de OLTP en memoria encuentra el punto de entrada del archivo DLL para el procedimiento almacenado.The In-Memory OLTP runtime locates the DLL entry point for the stored procedure.

  4. El código máquina del archivo DLL se ejecuta y los resultados se devuelven al cliente.The machine code in the DLL is executed and the results of are returned to the client.

Examen de parámetrosParameter sniffing

Los procedimientos almacenados de Transact-SQLTransact-SQL interpretado se compilan en la primera ejecución, a diferencia de los procedimientos almacenados compilados de forma nativa, que se compilan en el momento de su creación.Interpreted Transact-SQLTransact-SQL stored procedures are compiled at first execution, in contrast to natively compiled stored procedures, which are compiled at create time. Cuando los procedimientos almacenados interpretados se compilan al invocarlos, el optimizador usa los valores de los parámetros proporcionados para esta invocación al generar el plan de ejecución.When interpreted stored procedures are compiled at invocation, the values of the parameters supplied for this invocation are used by the optimizer when generating the execution plan. Este uso de parámetros durante la compilación se denomina examen de parámetros.This use of parameters during compilation is called parameter sniffing.

El examen de parámetros no se utiliza para compilar procedimientos almacenados compilados de forma nativa.Parameter sniffing is not used for compiling natively compiled stored procedures. Todos los parámetros para el procedimiento almacenado se considera que tienen valores UNKNOWN.All parameters to the stored procedure are considered to have UNKNOWN values. Al igual que sucede con los procedimientos almacenados interpretados, los procedimientos almacenados compilados de forma nativa también admiten la sugerencia OPTIMIZE FOR .Like interpreted stored procedures, natively compiled stored procedures also support the OPTIMIZE FOR hint. Para obtener más información, vea Sugerencias de consulta (Transact-SQL).For more information, see Query Hints (Transact-SQL).

Recuperar un plan de ejecución de consultas para los procedimientos almacenados compilados de forma nativaRetrieving a Query Execution Plan for Natively Compiled Stored Procedures

El plan de ejecución de consulta para un procedimiento almacenado compilado de forma nativa se puede recuperar con un Plan de ejecución estimado en Management StudioManagement Studioo con la opción SHOWPLAN_XML en Transact-SQLTransact-SQL.The query execution plan for a natively compiled stored procedure can be retrieved using Estimated Execution Plan in Management StudioManagement Studio, or using the SHOWPLAN_XML option in Transact-SQLTransact-SQL. Por ejemplo:For example:

SET SHOWPLAN_XML ON  
GO  
EXEC dbo.usp_myproc  
GO  
SET SHOWPLAN_XML OFF  
GO  

El plan de ejecución generado por el optimizador de consultas está compuesto de un árbol con operadores de consulta en los nodos y en las hojas de árbol.The execution plan generated by the query optimizer consists of a tree with query operators on the nodes and leaves of the tree. La estructura del árbol determina la interacción (el flujo de filas de un operador a otro) entre los operadores.The structure of the tree determines the interaction (the flow of rows from one operator to another) between the operators. En la vista gráfica de SQL Server Management StudioSQL Server Management Studio, el flujo es de derecha a izquierda.In the graphical view of SQL Server Management StudioSQL Server Management Studio, the flow is from right to left. Por ejemplo, el plan de consulta de la ilustración 1 contiene dos operadores de examen de índices, lo que proporciona filas para un operador de combinación de mezcla.For example, the query plan in figure 1 contains two index scan operators, which supplies rows to a merge join operator. El operador merge join proporciona filas para un operador select.The merge join operator supplies rows to a select operator. El operador select, finalmente, devuelve las filas al cliente.The select operator, finally, returns the rows to the client.

Operadores de consulta en procedimientos almacenados compilados de forma nativaQuery Operators in Natively Compiled Stored Procedures

En la tabla siguiente se resumen los operadores de consulta admitidos dentro de procedimientos almacenados compilados de forma nativa:The following table summarizes the query operators supported inside natively compiled stored procedures:

OperatorOperator Consulta de ejemploSample query NotasNotes
SELECTSELECT SELECT OrderID FROM dbo.[Order]
INSERTINSERT INSERT dbo.Customer VALUES ('abc', 'def')
UPDATEUPDATE UPDATE dbo.Customer SET ContactName='ghi' WHERE CustomerID='abc'
DeleteDELETE DELETE dbo.Customer WHERE CustomerID='abc'
Compute ScalarCompute Scalar SELECT OrderID+1 FROM dbo.[Order] Este operador se usa tanto para las funciones intrínsecas como para las conversiones de tipos.This operator is used both for intrinsic functions and type conversions. No todas las funciones y conversiones de tipos se admiten en los procedimientos almacenados compilados de forma nativa.Not all functions and type conversions are supported inside natively compiled stored procedures.
Combinación de bucles anidadosNested Loops Join SELECT o.OrderID, c.CustomerID FROM dbo.[Order] o INNER JOIN dbo.[Customer] c Nested Loops es el único operador de combinación admitido en los procedimientos almacenados compilados de forma nativa.Nested Loops is the only join operator supported in natively compiled stored procedures. Todos los planes que contienen combinaciones utilizarán el operador Nested Loops, incluso si el plan para la misma consulta ejecutada como Transact-SQLTransact-SQL interpretado contiene una combinación de mezcla o hash.All plans that contain joins will use the Nested Loops operator, even if the plan for same query executed as interpreted Transact-SQLTransact-SQL contains a hash or merge join.
SortSort SELECT ContactName FROM dbo.Customer ORDER BY ContactName
TOPTop SELECT TOP 10 ContactName FROM dbo.Customer
Top-sortTop-sort SELECT TOP 10 ContactName FROM dbo.Customer ORDER BY ContactName La expresión TOP (número de filas que se van a devolver) no puede superar 8000 filas.The TOP expression (the number of rows to be returned) cannot exceed 8,000 rows. Si hay también en la consulta operadores de combinación y agregación, habrá menos filas.Fewer if there are also join and aggregation operators in the query. Las combinaciones y agregaciones suelen reducir el número de filas que se van a ordenar, en comparación con el recuento de filas de las tablas base.Joins and aggregation do typically reduce the number of rows to be sorted, compared with the row count of the base tables.
Stream AggregateStream Aggregate SELECT count(CustomerID) FROM dbo.Customer Observe que el operador Hash Match no se admite para la agregación.Note that the Hash Match operator is not supported for aggregation. Por consiguiente, toda la agregación en los procedimientos almacenados compilados de forma nativa utiliza el operador Stream Aggregate, incluso si el plan para la misma consulta en Transact-SQLTransact-SQL interpretado utiliza el operador Hash Match.Therefore, all aggregation in natively compiled stored procedures uses the Stream Aggregate operator, even if the plan for the same query in interpreted Transact-SQLTransact-SQL uses the Hash Match operator.

Combinaciones y estadísticas de columnasColumn Statistics and Joins

SQL ServerSQL Server mantiene estadísticas en los valores de columnas de clave de índice para ayudar a evaluar el costo de ciertas operaciones, como el examen de índice y las búsquedas de índice.maintains statistics on values in index key columns to help estimate the cost of certain operations, such as index scan and index seeks. (SQL ServerSQL Server también crea estadísticas en columnas de clave sin índice si se crean explícitamente o si el optimizador de consultas las crea en respuesta a una consulta con predicado). La métrica principal en la estimación del costo es el número de filas procesadas por un único operador.( SQL ServerSQL Server also creates statistics on non-index key columns if you explicitly create them or if the query optimizer creates them in response to a query with a predicate.) The main metric in cost estimation is the number of rows processed by a single operator. Tenga en cuenta que para las tablas basadas en disco, el número de páginas a las que tiene acceso un operador determinado es importante en la estimación de costos.Note that for disk-based tables, the number of pages accessed by a particular operator is significant in cost estimation. Sin embargo, como el recuento de páginas no es importante para las tablas optimizadas para memoria (siempre es cero), esta explicación se centra en el recuento de filas.However, as page count is not important for memory-optimized tables (it is always zero), this discussion focuses on row count. La estimación comienza por los operadores de examen y búsqueda de índice en el plan, y se extiende después para incluir los otros operadores, como el operador de combinación.The estimation starts with the index seek and scan operators in the plan, and is then extended to include the other operators, like the join operator. El número estimado de filas que va a procesar un operador de combinación se basa en la estimación de los operadores de examen, índice y búsqueda subyacentes.The estimated number of rows to be processed by a join operator is based on the estimation for the underlying index, seek, and scan operators. Para que Transact-SQLTransact-SQL interpretado pueda obtener acceso a las tablas optimizadas para memoria, puede seguir el plan de ejecución real para ver la diferencia entre los recuentos de filas estimado y real de los operadores del plan.For interpreted Transact-SQLTransact-SQL access to memory-optimized tables, you can observe the actual execution plan to see the difference between the estimated and actual row counts for the operators in the plan.

Para el ejemplo en la ilustración 1,For the example in figure 1,

  • El examen de índice clúster en Customer ha estimado 91; reales 91.The clustered index scan on Customer has estimated 91; actual 91.
  • El examen de índice no clúster en CustomerID ha estimado 830; reales 830.The nonclustered index scan on CustomerID has estimated 830; actual 830.
  • El operador Merge Join ha estimado 815; reales 830.The Merge Join operator has estimated 815; actual 830.

Las estimaciones de los exámenes de índice son precisas.The estimates for the index scans are accurate. SQL ServerSQL Server mantiene el recuento de filas en las tablas basadas en disco.maintains the row count for disk-based tables. Las estimaciones para los recorridos de índice y de la tabla completa siempre son precisas.Estimates for full table and index scans are always accurate. La estimación de la combinación es bastante precisa también.The estimate for the join is fairly accurate, too.

Si estas estimaciones cambian, las consideraciones de costo para las diferentes alternativas de plan también cambian.If these estimates change, the cost considerations for different plan alternatives change as well. Por ejemplo, si uno de los lados de la combinación tiene un recuento estimado de filas de 1 o menos, usar las combinaciones de bucles anidados es menos costoso.For example, if one of the sides of the join has an estimated row count of 1 or just a few rows, using a nested loops joins is less expensive. Considere la siguiente consulta:Consider the following query:

SELECT o.OrderID, c.* FROM dbo.[Customer] c INNER JOIN dbo.[Order] o ON c.CustomerID = o.CustomerID  

Después de eliminar todas las filas menos una en la tabla Customer, se genera el plan de consulta siguiente:After deleting all rows but one in the Customer table, the following query plan is generated:

Combinaciones y estadísticas de columnas.Column statistics and joins.

Acerca de este plan de consulta:Regarding this query plan:

  • Hash Match se ha reemplazado por un operador de combinación anidada Nested Loops.The Hash Match has been replaced with a Nested Loops physical join operator.
  • El examen de índice completo en IX_CustomerID se ha reemplazado por index seek.The full index scan on IX_CustomerID has been replaced with an index seek. Esto provocó el examen de 5 filas en lugar de las 830 necesarias para el examen de índice completo.This resulted in scanning 5 rows, instead of the 830 rows required for the full index scan.

Consulte tambiénSee Also

Tablas optimizadas para la memoriaMemory-Optimized Tables