¿Por qué la sugerencia READPAST hace que se ignoren las vistas indexadas?


10

Estoy investigando el uso de la READPASTsugerencia para reducir el bloqueo de recursos en el subsistema financiero de nuestra aplicación.

Parecía un buen camino porque los registros de transacciones financieras solo se agregan, nunca se actualizan o eliminan. Las únicas filas que alguna vez se omitirán son filas completamente nuevas insertadas dentro de una transacción; efectivamente no existen en el mundo exterior hasta que se confirma la transacción.

Sin embargo, noté un peor rendimiento en las consultas que utilizan vistas indexadas en las que había puesto la READPASTpista. Al comparar los planes de consulta, parece que con la sugerencia, el optimizador de consultas elige no usar la vista indexada y, en cambio, recurre a tratarla como una vista normal.

No estoy seguro de por qué sería eso; Me imagino que las vistas indexadas son como cualquier otro índice, ya que las teclas se pueden bloquear durante las operaciones y agregar READPASTfuncionaría de manera similar.

SELECT TOP 1 isa.InvoiceId
FROM Financial_InvoiceSummaryAmounts isa WITH (READPAST)
WHERE isa.TotalOwedAmount = 0.0

ingrese la descripción de la imagen aquí

SELECT TOP 1 isa.InvoiceId
FROM Financial_InvoiceSummaryAmounts isa
WHERE isa.TotalOwedAmount = 0.0

ingrese la descripción de la imagen aquí

Agregar una NOEXPANDpista también parece funcionar, pero estoy interesado en aprender más sobre posiblemente por qué READPASTel optimizador de consultas tomó esa decisión en primer lugar (como parte de una respuesta completa).

Respuestas:


7

Reutilizando la tabla de ejemplo y la vista indizada de mi artículo Otra razón para usar NOEXPANDsugerencias en Enterprise Edition :

CREATE TABLE dbo.T
(
    col1 integer NOT NULL
);
GO
INSERT dbo.T WITH (TABLOCKX)
    (col1)
SELECT 
    SV.number
FROM master.dbo.spt_values AS SV
WHERE 
    SV.type = N'P';
GO
CREATE VIEW dbo.VT
WITH SCHEMABINDING
AS
SELECT T.col1 
FROM dbo.T AS T;

Repro

Esta consulta coincide con la vista indexada (aunque con un agregado redundante):

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT;

Vista indexada coincidente

Agregar una READPASTpista da como resultado el acceso a la tabla base:

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT 
    WITH (READPAST);

La vista indizada no coincide

Explicación

La READPASTsugerencia afecta semánticamente. El optimizador se resiste a reescribir consultas de modo que los resultados cambien. Para ilustrar:

La siguiente consulta se ejecuta sin problemas:

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT 
    WITH (READPAST);

Sin embargo:

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT 
    WITH (READPAST)
OPTION 
    (TABLE HINT (VT, FORCESCAN));

Produce el error:

Mensaje 8722, Nivel 16, Estado 1, Línea 42
No se puede ejecutar la consulta.
La sugerencia que afecta semánticamente 'readpast' aparece en la cláusula 'WITH' del objeto 'VT'
pero no en la correspondiente cláusula 'TABLE HINT'.
Cambie la cláusula OPTION (TABLE HINTS ...) para que el semántico afecte las sugerencias
coincide con la cláusula WITH.

Cuando hace referencia a la vista indizada sin la NOEXPANDsugerencia, la vista se expande (antes de que comience la compilación y la optimización) para hacer referencia a los objetos subyacentes. Más adelante en el proceso, el optimizador puede considerar hacer coincidir el árbol de consultas con una vista indizada, en su totalidad o en parte.

Cuando READPASTse usa sin NOEXPAND, la sugerencia se propaga a la tabla base, evitando la coincidencia de vistas (semántica diferente).

Con NOEXPAND, la sugerencia se aplica directamente a la vista, por lo que no hay problema.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.