Compartir a través de


Sugerencias de tabla (Transact-SQL)

Las sugerencias de tabla invalidan el comportamiento predeterminado del optimizador de consultas mientras dura la instrucción de lenguaje de manipulación de datos (DML), especificando un método de bloqueo, uno o varios índices, una operación de procesamiento de la consulta como, por ejemplo, un examen de tabla o Index Seek, u otras opciones.

Nota de advertenciaAdvertencia

Como el optimizador de consultas de SQL Server suele seleccionar el mejor plan de ejecución de una consulta, se recomienda que únicamente los administradores de bases de datos y desarrolladores experimentados utilicen las sugerencias como último recurso.

Se aplica a:

DELETE

INSERT

SELECT

UPDATE

MERGE

Icono de vínculo a temasConvenciones de sintaxis de Transact-SQL

Sintaxis

WITH ( <table_hint> [ [ , ]...n ] )

<table_hint> ::= 
[ NOEXPAND ] { 
    INDEX ( index_value [ ,...n ] ) | INDEX = ( index_value )
  | FASTFIRSTROW 
  | FORCESEEK
  | HOLDLOCK 
  | NOLOCK 
  | NOWAIT
  | PAGLOCK 
  | READCOMMITTED 
  | READCOMMITTEDLOCK 
  | READPAST 
  | READUNCOMMITTED 
  | REPEATABLEREAD 
  | ROWLOCK 
  | SERIALIZABLE 
  | TABLOCK 
  | TABLOCKX 
  | UPDLOCK 
  | XLOCK 
} 

<table_hint_limited> ::=
{
    KEEPIDENTITY 
  | KEEPDEFAULTS 
  | FASTFIRSTROW 

  | HOLDLOCK 
  | IGNORE_CONSTRAINTS 
  | IGNORE_TRIGGERS 
  | NOWAIT
  | PAGLOCK 
  | READCOMMITTED 
  | READCOMMITTEDLOCK 
  | READPAST 
  | REPEATABLEREAD 
  | ROWLOCK 
  | SERIALIZABLE 
  | TABLOCK 
  | TABLOCKX 
  | UPDLOCK 
  | XLOCK 
} 

Argumentos

  • WITH ( <table_hint> ) [ [ , ]...n ]
    Con algunas excepciones, las sugerencias de tabla se admiten en la cláusula FROM únicamente cuando las sugerencias se especifican con la palabra clave WITH. Las sugerencias de tabla deben especificarse también con paréntesis.

    Nota importanteImportante

    Omitir la palabra clave WITH es una característica obsoleta: Esta característica se quitará en una versión futura de Microsoft SQL Server. Evite utilizar esta característica en nuevos trabajos de desarrollo y tenga previsto modificar las aplicaciones que actualmente la utilizan.

    Las sugerencias de tabla permitidas con y sin la palabra clave WITH son las siguientes: NOLOCK, READUNCOMMITTED, UPDLOCK, REPEATABLEREAD, SERIALIZABLE, READCOMMITTED, FASTFIRSTROW, TABLOCK, TABLOCKX, PAGLOCK, ROWLOCK, NOWAIT, READPAST, XLOCK y NOEXPAND. Cuando estas sugerencias de tabla se especifican sin la palabra clave WITH, deben especificarse solas. Por ejemplo:

    FROM t (TABLOCK)
    

    Cuando la sugerencia se especifica con otra opción, debe especificarse con la palabra clave WITH:

    FROM t WITH (TABLOCK, INDEX(myindex))
    

    Recomendamos utilizar comas entre las sugerencias de tabla.

    Nota importanteImportante

    La separación de las sugerencias con espacios en lugar de comas es una característica obsoleta: Esta característica se quitará en una versión futura de Microsoft SQL Server. No utilice esta característica en nuevos trabajos de desarrollo y modifique lo antes posible las aplicaciones que actualmente la utilizan.

    Las restricciones se aplican cuando las sugerencias se utilizan en consultas de bases de datos con un nivel de compatibilidad de 90 y superior.

  • NOEXPAND
    Especifica que las vistas indizadas no se expandan para obtener acceso a las tablas subyacentes cuando el optimizador de consultas procesa la consulta. El optimizador de consultas trata la vista como una tabla con un índice clúster. NOEXPAND solamente se aplica a las vistas indizadas. Para obtener más información, vea la sección Notas.

  • INDEX ( index_value [ ,... n ] ) | INDEX = ( index_value )
    La sintaxis de INDEX() especifica los nombres o los identificadores de los índices que el optimizador de consultas va a utilizar al procesar la instrucción. La sintaxis alternativa INDEX = especifica un valor de índice único. Solamente se puede especificar una sugerencia de índice por cada tabla.

    Si existe un índice clúster, INDEX(0) exige un examen del índice clúster e INDEX(1) exige un examen o una búsqueda del índice clúster. Si no existe un índice clúster, INDEX(0) exige un examen de la tabla e INDEX(1) se interpreta como error.

    Si se utilizan varios índices en una lista de sugerencias, los índices duplicados se omiten y el resto se utiliza para recuperar las filas de la tabla. El orden de los índices de la sugerencia de índice es importante. Una sugerencia de varios índices obliga a hacer AND entre los índices y el optimizador de consultas aplica todas las condiciones posibles a cada uno de los índices a los que tiene acceso. Si la colección de índices sugeridos no incluye todas las columnas a las que hace referencia la consulta, se realiza una captura para recuperar las columnas restantes, una vez que SQL Server Database Engine (Motor de base de datos de SQL Server) recupera todas las columnas indizadas.

    [!NOTA]

    Cuando se utiliza una sugerencia de índice que hace referencia a varios índices en la tabla de hechos de una combinación en estrella, el optimizador pasa por alto la sugerencia de índice y devuelve un mensaje de advertencia. Asimismo, no se admiten las operaciones OR de índices para una tabla con una sugerencia de índice especificada.

    El número máximo de índices de una sugerencia de tabla es 250 índices no clúster.

  • KEEPIDENTITY
    Solamente se aplica a una instrucción INSERT cuando se utiliza la opción BULK con OPENROWSET.

    Especifica que se debe utilizar uno o varios valores de identidad en el archivo de datos importado para la columna de identidad. Si no se especifica KEEPIDENTITY, los valores de identidad de esta columna se comprueban pero no se importan, y el optimizador de consultas asigna automáticamente valores únicos basados en los valores de inicialización y de incremento especificados durante la creación de la tabla.

    Nota importanteImportante

    Si el archivo de datos no contiene valores para la columna de identidad de la tabla o vista, y la columna de identidad no es la última columna de la tabla, entonces deberá omitir la columna de identidad. Para obtener más información, vea Usar un archivo de formato para omitir un campo de datos. Si una columna de identidad se omite correctamente, el optimizador de consultas asigna automáticamente valores únicos para la columna de identidad en las filas importadas de la tabla.

    Para obtener un ejemplo que utiliza esta sugerencia en una instrucción INSERT... Para la instrucción SELECT * FROM OPENROWSET(BULK...), vea Mantener valores de identidad al importar datos de forma masiva.

    Para obtener información acerca de cómo comprobar el valor de identidad de una tabla, vea DBCC CHECKIDENT (Transact-SQL).

  • KEEPDEFAULTS
    Solamente se aplica a una instrucción INSERT cuando se utiliza la opción BULK con OPENROWSET.

    Especifica la inserción del valor predeterminado de la columna de una tabla, si existe, en lugar de NULL, cuando falta el valor del registro de datos de esa columna.

    Para obtener un ejemplo que utiliza esta sugerencia en una instrucción INSERT... Para la instrucción SELECT * FROM OPENROWSET(BULK...), vea Mantener valores NULL o utilizar valores predeterminados durante la importación masiva.

  • FASTFIRSTROW
    Equivalente a OPTION (FAST 1). Para obtener más información, vea Sugerencias de consulta (Transact-SQL).

    Nota importanteImportante

    Esta característica se quitará en la versión siguiente de Microsoft SQL Server. No utilice esta característica en nuevos trabajos de desarrollo y modifique lo antes posible las aplicaciones que actualmente la utilizan.

  • FORCESEEK
    Especifica que el optimizador de consultas use solamente una operación de búsqueda de índices como ruta de acceso a los datos de la tabla o vista a la que se hace referencia en la consulta.

    FORCESEEK se aplica a operaciones de búsqueda de índices clúster y no clúster. Se puede especificar para cualquier tabla o vista en la cláusula FROM de una instrucción SELECT y en la cláusula FROM <table_source> de una instrucción UPDATE, MERGE o DELETE.

    FORCESEEK se puede especificar con o sin una sugerencia INDEX. Cuando se combina con una sugerencia de índice, el optimizador de consultas solamente busca rutas de acceso a través del índice especificado. Si FORCESEEK hace que no se encuentre ningún plan, se devuelve el error 8622. Para obtener más información, vea Utilizar la sugerencia de tabla FORCESEEK.

  • HOLDLOCK
    Equivalente a SERIALIZABLE. Para obtener más información, vea SERIALIZABLE más adelante en este tema. HOLDLOCK solamente se aplica a la tabla o vista para la que se especificó, y únicamente durante la transacción definida por la instrucción en la que se utiliza. HOLDLOCK no se puede utilizar en una instrucción SELECT que incluya la opción FOR BROWSE.

  • IGNORE_CONSTRAINTS
    Solamente se aplica a una instrucción INSERT cuando se utiliza la opción BULK con OPENROWSET.

    Especifica que la operación de importación masiva ignora las restricciones de la tabla. De forma predeterminada, INSERT comprueba las restricciones CHECK y FOREIGN KEY. Cuando IGNORE_CONSTRAINTS se especifica para una operación de importación masiva, INSERT debe ignorar estas restricciones en una tabla de destino. Tenga en cuenta que no puede deshabilitar las restricciones UNIQUE, PRIMARY KEY o NOT NULL.

    Puede ser conveniente deshabilitar las instrucciones CHECK y FOREING KEY si los datos de entrada contienen filas que infringen las restricciones. Si se deshabilitan las restricciones CHECK y FOREIGN KEY, se pueden importar los datos y, a continuación, utilizar instrucciones Transact-SQL para limpiarlos.

    Sin embargo, si se ignoran las restricciones CHECK y FOREIGN KEY, cada una de las restricciones ignoradas de la tabla se marcará como is_not_trusted en las vistas de catálogo sys.check_constraints o sys.foreign_keys después de la operación. En algún momento, deberá comprobar las restricciones en la tabla completa. Si la tabla no estaba vacía antes de la operación de importación masiva, el costo de volver a validar la restricción puede ser mayor que el costo de aplicar las restricciones CHECK o FOREIGN KEY a los datos incrementales.

  • IGNORE_TRIGGERS
    Solamente se aplica a una instrucción INSERT cuando se utiliza la opción BULK con OPENROWSET.

    Especifica que la operación de importación masiva ignore todos los desencadenadores definidos en la tabla. De manera predeterminada, INSERT aplica desencadenadores.

    Use IGNORE_TRIGGERS únicamente si su aplicación no depende de ningún desencadenador y es importante maximizar el rendimiento.

  • NOLOCK
    Equivalente a READUNCOMMITTED. Para obtener más información, vea READUNCOMMITTED más adelante en este mismo tema.

    [!NOTA]

    Para las instrucciones UPDATE o DELETE: Esta característica se quitará en una versión futura de Microsoft SQL Server. Evite utilizar esta característica en nuevos trabajos de desarrollo y tenga previsto modificar las aplicaciones que actualmente la utilizan.

  • NOWAIT
    Indica a Database Engine (Motor de base de datos) que devuelva un mensaje cuando encuentre un bloqueo en la tabla. NOWAIT equivale a especificar SET LOCK_TIMEOUT 0 para una tabla específica.

  • PAGLOCK
    Aplica bloqueos de página en los casos en que se suelen aplicar bloqueos individuales en filas o claves, o bien en los casos en los que se suele aplicar un único bloqueo de tabla. De manera predeterminada, utiliza el modo de bloqueo apropiado para la operación. Cuando se especifica en transacciones que funcionan con el nivel de aislamiento SNAPSHOT, no se utilizan bloqueos de página a menos que se combine PAGLOCK con otras sugerencias de tabla que requieran bloqueos, como UPDLOCK y HOLDLOCK.

  • READCOMMITTED
    Especifica que las operaciones de lectura cumplan las reglas del nivel de aislamiento READ COMMITTED, a través del uso de bloqueos o control de versiones de filas. Si la opción de la base de datos READ_COMMITTED_SNAPSHOT está establecida en OFF, Database Engine (Motor de base de datos) adquiere bloqueos compartidos a medida que se leen los datos y los libera cuando finaliza la operación de lectura. Si la opción de base de datos READ_COMMITTED_SNAPSHOT está establecida en ON, el Database Engine (Motor de base de datos) no adquiere bloqueos y utiliza el control de versiones de filas. Para obtener más información acerca de los niveles de aislamiento, vea SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

    [!NOTA]

    Para las instrucciones UPDATE o DELETE: Esta característica se quitará en una versión futura de Microsoft SQL Server. Evite utilizar esta característica en nuevos trabajos de desarrollo y tenga previsto modificar las aplicaciones que actualmente la utilizan.

  • READCOMMITTEDLOCK
    Especifica que las operaciones de lectura cumplan, mediante el uso de bloqueos, las reglas del nivel de aislamiento READ COMMITTED. El Database Engine (Motor de base de datos) adquiere bloqueos compartidos a medida que se leen los datos y los libera cuando finaliza la operación de lectura, independientemente de la configuración de la opción de base de datos READ_COMMITTED_SNAPSHOT. Para obtener más información acerca de los niveles de aislamiento, vea SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

  • READPAST
    Especifica que Database Engine (Motor de base de datos) no lea las filas bloqueadas por otras transacciones. En la mayoría de las circunstancias, sucede lo mismo con las páginas. Cuando se especifica READPAST, se omiten los bloqueos tanto en el nivel de fila como en el de página. Es decir, Database Engine (Motor de base de datos) omite las filas o las páginas en lugar de bloquear la transacción actual hasta que se liberen los bloqueos. Suponga, por ejemplo, una tabla T1 que contiene una única columna de tipo entero con los valores 1, 2, 3, 4, 5. Si una transacción A cambia el valor de 3 a 8 pero aún no se ha confirmado, una instrucción SELECT * FROM T1 (READPAST) generará los valores 1, 2, 4, 5. READPAST se utiliza principalmente para reducir el conflicto de bloqueos cuando se implementa una cola de trabajo que utiliza una tabla de SQL Server. Un lector de cola que utilice READPAST omite las entradas de cola bloqueadas por otras transacciones y pasa a la siguiente entrada de cola disponible, sin tener que esperar a que las otras transacciones liberen los bloqueos.

    READPAST se puede especificar para cualquier tabla a la que se haga referencia en una instrucción UPDATE o DELETE, o en una cláusula FROM. Cuando se especifica en una instrucción UPDATE, READPAST solamente se aplica al leer los datos para identificar los registros que se van a actualizar, independientemente de dónde se especifique en la instrucción. No se puede especificar READPAST para tablas en la cláusula INTO de una instrucción INSERT. Las operaciones de lectura que utilizan READPAST no se bloquean. Las operaciones de actualización o eliminación que utilizan READPAST se pueden bloquear al leer claves externas o vistas indizadas, o al modificar índices secundarios.

    READPAST solamente se puede especificar en transacciones que funcionen con niveles de aislamiento READ COMMITTED o REPEATABLE READ. Cuando se especifica en transacciones que funcionan con el nivel de aislamiento SNAPSHOT, READPAST debe combinarse con otras sugerencias de tabla que requieran bloqueos, como UPDLOCK y HOLDLOCK.

    No se puede especificar la sugerencia de tabla READPAST cuando la opción de base de datos READ_COMMITTED_SNAPSHOT esté establecida en ON y se cumpla alguna de las condiciones siguientes.

    • El nivel de aislamiento de transacción de la sesión es READ COMMITTED.

    • La sugerencia de tabla READCOMMITTED también se especifica en la consulta.

    Para especificar la sugerencia READPAST en estos casos, quite la sugerencia de tabla READCOMMITTED, si está presente, e incluya la sugerencia de tabla READCOMMITTEDLOCK en la consulta.

  • READUNCOMMITTED
    Especifica que se admiten lecturas no actualizadas. No se emiten bloqueos compartidos para impedir que otras transacciones modifiquen los datos leídos por la transacción actual, mientras que los bloqueos exclusivos establecidos por otras transacciones no impiden que la transacción actual lea los datos bloqueados. La posibilidad de efectuar lecturas no actualizadas aumenta en gran medida la simultaneidad, pero a costa de leer modificaciones de datos que otras transacciones revierten más adelante. Esto puede generar errores en la transacción, presentar a los usuarios datos no confirmados o hacer que los usuarios vean los registros dos veces (o nunca). Para obtener más información acerca de las lecturas de datos no actualizados, las lecturas no repetibles y las lecturas ficticias, vea Efectos de la simultaneidad.

    Las sugerencias READUNCOMMITTED y NOLOCK solamente se aplican a bloqueos de datos. Todas las consultas, incluidas las que tienen sugerencias READUNCOMMITTED y NOLOCK, adquieren bloqueos Sch-S (estabilidad del esquema) durante la compilación y la ejecución. Debido a ello, las consultas se bloquean cuando una transacción simultánea aloja un bloqueo de modificación del esquema (Sch-M) en la tabla. Por ejemplo, una operación de lenguaje de definición de datos (DDL) adquiere un bloqueo Sch-M antes de modificar la información del esquema de la tabla. Las consultas simultáneas, incluidas las que se ejecutan con sugerencias READUNCOMMITTED o NOLOCK, se bloquean cuando intentan adquirir un bloqueo Sch-S. A la inversa, una consulta que mantiene un bloqueo Sch-S bloquea una transacción simultánea que intenta adquirir un bloqueo Sch-M. Para obtener más información acerca del comportamiento de bloqueo, vea Compatibilidad de bloqueos (motor de base de datos).

    No se pueden especificar READUNCOMMITTED ni NOLOCK en tablas modificadas por operaciones de inserción, actualización y eliminación. El optimizador de consultas de SQL Server omite las sugerencias READUNCOMMITTED y NOLOCK de la cláusula FROM que se aplica a la tabla de destino de una instrucción UPDATE o DELETE.

    [!NOTA]

    En una versión futura de SQL Server se quitará el uso de las sugerencias READUNCOMMITTED y NOLOCK en la cláusula FROM que se aplican a la tabla de destino de una instrucción UPDATE o DELETE. Evite usar estas sugerencias en este contexto en el nuevo trabajo de desarrollo y planee modificar las aplicaciones que las usan actualmente.

    Si lo desea, también puede reducir al mínimo el conflicto de bloqueos mientras protege las transacciones de lecturas de datos no actualizados de modificaciones de datos no confirmadas mediante una de estas dos alternativas:

    • El nivel de aislamiento READ COMMITTED con la opción de base de datos READ_COMMITTED_SNAPSHOT establecida en ON.

    • El nivel de aislamiento SNAPSHOT.

    Para obtener más información acerca de los niveles de aislamiento, vea SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

    [!NOTA]

    Si al especificar READUNCOMMITTED, recibe el mensaje de error 601, resuélvalo como si fueran errores de interbloqueo (1205) y vuelva a ejecutar la instrucción.

  • REPEATABLEREAD
    Especifica que el examen se haga con la misma semántica de bloqueo que una transacción que se ejecute con el nivel de aislamiento REPEATABLE READ. Para obtener más información acerca de los niveles de aislamiento, vea SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

  • ROWLOCK
    Especifica que se apliquen bloqueos de fila cuando normalmente se aplicarían bloqueos de página o de tabla. Cuando se especifica en transacciones que funcionan con el nivel de aislamiento SNAPSHOT, no se utilizan bloqueos de fila a menos que se combine ROWLOCK con otras sugerencias de tabla que requieran bloqueos, como UPDLOCK y HOLDLOCK.

  • SERIALIZABLE
    Equivalente a HOLDLOCK. Hace que los bloqueos compartidos sean más restrictivos, manteniéndolos hasta la finalización de la transacción, en lugar de liberarlos cuando la tabla o página de datos deja de ser necesaria, se haya completado la transacción o no. El examen se hace con la misma semántica que una transacción que se ejecuta con el nivel de aislamiento SERIALIZABLE. Para obtener más información acerca de los niveles de aislamiento, vea SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

  • TABLOCK
    Especifica que un bloqueo compartido de tabla se aplique hasta el final de la instrucción. Si también se especifica HOLDLOCK, el bloqueo de tabla compartido se mantiene hasta el final de la transacción.

    Al importar los datos en un montón utilizando la instrucción INSERT INTO <target_table> SELECT <columns> FROM <source_table>, puede habilitar el registro optimizado y el bloqueo de la instrucción especificando la sugerencia TABLOCK para la tabla de destino. Además, el modelo de recuperación de la base de datos debe establecerse en registro simple o masivo. Para obtener más información, vea INSERT (Transact-SQL).

    Cuando se utiliza con el proveedor de conjuntos de filas BULK OPENROWSET para importar los datos en una tabla, TABLOCK permite que varios clientes carguen datos simultáneamente en la tabla de destino, con el bloqueo y el registro optimizados. Para obtener más información, vea Requisitos previos para el registro mínimo durante la importación masiva.

  • TABLOCKX
    Especifica que se aplique un bloqueo exclusivo en la tabla.

  • UPDLOCK
    Especifica que se apliquen bloqueos de actualización y se mantengan hasta que se complete la transacción.

  • XLOCK
    Especifica que se apliquen bloqueos exclusivos y se mantengan hasta que finalice la transacción. Si se especifica junto con ROWLOCK, PAGLOCK o TABLOCK, los bloqueos exclusivos se aplican al nivel de granularidad apropiado.

Notas

Las sugerencias de tabla se pasan por alto si el plan de consulta no tiene acceso a la tabla. Esto puede deberse a que el optimizador elija no tener acceso a la tabla o a que, en su lugar, se tenga acceso a una vista indizada. En el último caso, el acceso a una vista indizada puede evitarse con la sugerencia de consulta OPTION (EXPAND VIEWS).

Todas las sugerencias de bloqueo se propagan a todas las tablas y vistas a las que tiene acceso el plan de consulta, incluidas las tablas y vistas a las que se hace referencia en una vista. Asimismo, SQL Server lleva a cabo las comprobaciones de coherencia de bloqueo correspondientes.

Las sugerencias de bloqueo ROWLOCK, UPDLOCK y XLOCK que adquieren bloqueos de nivel de fila pueden aplicar bloqueos a claves de índice en lugar de a las filas de datos. Por ejemplo, si una tabla tiene un índice no clúster y un índice de cobertura controla una instrucción SELECT que utiliza una sugerencia de bloqueo, se aplicará un bloqueo a la clave de índice en el índice de cobertura en lugar de aplicarse a la fila de datos de la tabla base.

Si una tabla contiene columnas calculadas y los cálculos de dichas columnas se hacen con expresiones o funciones que tienen acceso a columnas de otras tablas, las sugerencias de tabla no se utilizan en las otras tablas. Esto significa que las sugerencias de tabla no se propagan. Por ejemplo, una sugerencia de tabla NOLOCK se especifica para una tabla de la consulta. Esta tabla tiene columnas calculadas que se calculan mediante una combinación de expresiones y funciones que tienen acceso a columnas de otra tabla. En las tablas a las que hacen referencia estas expresiones y funciones no se utiliza la sugerencia de tabla NOLOCK cuando se tiene acceso.

SQL Server no permite más de una sugerencia de tabla de cada uno de los siguientes grupos para cada tabla en la cláusula FROM:

  • Sugerencias de granularidad: PAGLOCK, NOLOCK, ROWLOCK, TABLOCK o TABLOCKX.

  • Sugerencias de nivel de aislamiento: HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE.

Sugerencias de índice filtrado

Un índice filtrado se puede utilizar como sugerencia de tabla, pero hará que el optimizador de consultas genere el error 8622 si no cubre todas las filas que selecciona la consulta. A continuación se muestra un ejemplo de una sugerencia de índice filtrado no válida. En el ejemplo se crea el índice filtrado FIBillOfMaterialsWithComponentID que, a continuación, se utiliza como una sugerencia de índice para una instrucción SELECT. El predicado de índice filtrado incluye las filas de datos para los ComponentID 533, 324 y 753. El predicado de consulta también incluye las filas de datos para los ComponentID 533, 324 y 753, pero amplía el conjunto de resultados para incluir los ComponentID 855 y 924, que no están en el índice filtrado. Por consiguiente, el optimizador de consultas no puede utilizar la sugerencia de índice filtrado y genera el error 8622. Para obtener más información, vea Directrices generales para diseñar índices filtrados.

USE AdventureWorks;
GO
IF EXISTS (SELECT name FROM sys.indexes
    WHERE name = N'FIBillOfMaterialsWithComponentID' 
    AND object_id = OBJECT_ID(N'Production.BillOfMaterials'))
DROP INDEX FIBillOfMaterialsWithComponentID
    ON Production.BillOfMaterials;
GO
CREATE NONCLUSTERED INDEX "FIBillOfMaterialsWithComponentID"
    ON Production.BillOfMaterials (ComponentID, StartDate, EndDate)
    WHERE ComponentID IN (533, 324, 753);
GO
SELECT StartDate, ComponentID FROM Production.BillOfMaterials
    WITH( INDEX (FIBillOfMaterialsWithComponentID) )
    WHERE ComponentID in (533, 324, 753, 855, 924);
GO

El optimizador de consultas no considerará una sugerencia de índice si las opciones SET no tienen los valores necesarios para los índices filtrados. Para obtener más información, vea CREATE INDEX (Transact-SQL).

Usar NOEXPAND

NOEXPAND solamente se aplica a las vistas indizadas. Una vista indizada es una vista con un único índice clúster creado en ella. Si una consulta tiene referencias a columnas que están presentes en una vista indizada y en tablas base, y el optimizador de consultas determina que el uso de vistas indizadas proporciona el mejor método para ejecutar la consulta, el optimizador de consultas utiliza el índice en la vista. Esta función se denomina coincidencia de vista indizada y solamente se admite en las ediciones Enterprise y Developer de SQL Server.

Sin embargo, para que el optimizador considere las vistas indizadas para establecer coincidencias o utilice una vista indizada a la que se hace referencia con una sugerencia NOEXPAND, las siguientes opciones SET deben estar establecidas en ON:

ANSI_NULLS

ANSI_WARNINGS

CONCAT_NULL_YIELDS_NULL

ANSI_PADDING

ARITHABORT1

QUOTED_IDENTIFIERS

1 ARITHABORT se establece implícitamente en ON al establecer ANSI_WARNINGS en ON. Por lo tanto, no es necesario ajustar manualmente este valor.

Asimismo, la opción NUMERIC_ROUNDABORT debe establecerse en OFF.

Para exigir que el optimizador utilice un índice para una vista indizada, especifique la opción NOEXPAND. Esta sugerencia solamente se puede utilizar si la vista también aparece en la consulta. SQL Server no proporciona ninguna sugerencia que obligue a utilizar una vista indizada particular en una consulta que no mencione la vista directamente en la cláusula FROM. Sin embargo, el optimizador de consultas considera el uso de vistas indizadas, incluso si no se hace referencia directa a ellas en la consulta.

Para obtener más información, vea Resolver índices de vistas.

Usar una sugerencia de tabla como una sugerencia de consulta

Las sugerencias de tabla también se pueden especificar como sugerencias de consulta utilizando la cláusula OPTION (TABLE HINT). Solamente se recomienda usar una sugerencia de tabla como una sugerencia de consulta en el contexto de una guía de plan. Para las consultas ad hoc, especifique estas sugerencias únicamente como sugerencias de tabla. Para obtener más información, vea Sugerencias de consulta (Transact-SQL).

Permisos

Las sugerencias KEEPIDENTITY, IGNORE_CONSTRAINTS e IGNORE_TRIGGERS requieren permisos ALTER en la tabla.

Ejemplos

A. Usar la sugerencia TABLOCK para especificar un método de bloqueo

En el ejemplo siguiente se especifica que se aplique un bloqueo compartido a la tabla Production.Product y que se mantenga hasta que finalice la instrucción UPDATE.

USE AdventureWorks;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO

B. Usar la sugerencia FORCESEEK para especificar una operación de búsqueda de índices

En el ejemplo siguiente se utiliza la sugerencia FORCESEEK para obligar a que el optimizador de consultas realice una operación de búsqueda de índices en la tabla Sales.SalesOrderDetail.

USE AdventureWorks;
GO
SELECT *
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d WITH (FORCESEEK)
    ON h.SalesOrderID = d.SalesOrderID 
WHERE h.TotalDue > 100
AND (d.OrderQty > 5 OR d.LineTotal < 1000.00);
GO