Por que a dica READPAST faz com que as visualizações indexadas sejam ignoradas?

10

Estou investigando usando a READPASTdica para reduzir o bloqueio de recursos no subsistema financeiro de nosso aplicativo.

Parecia um bom caminho a percorrer, porque os registros de transações financeiras são sempre adicionados, nunca atualizados ou excluídos. As únicas linhas que seriam ignoradas são as novas linhas inseridas dentro de uma transação; eles efetivamente não existem no mundo externo até que a transação seja confirmada.

No entanto, notei um desempenho pior em consultas que utilizam exibições indexadas nas quais eu havia colocado a READPASTdica. Comparando os planos de consulta, parece que com a dica, o otimizador de consulta opta por não usar a exibição indexada e volta a tratá-la como uma exibição normal.

Não sei por que isso seria; Eu imagino que as exibições indexadas sejam como qualquer outro índice, pois as chaves podem ser bloqueadas durante as operações e a adição READPASTfuncionaria da mesma forma.

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

insira a descrição da imagem aqui

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

insira a descrição da imagem aqui

A adição de uma NOEXPANDdica também parece funcionar, mas estou interessado em aprender mais sobre o motivo READPASTpelo qual o otimizador de consulta fez essa escolha em primeiro lugar (como parte de uma resposta completa).

Marte
fonte

Respostas:

7

Reutilizando a tabela de exemplo e a exibição indexada do meu artigo Outro motivo para usar NOEXPANDdicas no 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 corresponde à exibição indexada (embora com um agregado redundante):

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

Visualização indexada correspondente

A adição de uma READPASTdica resulta no acesso à tabela base:

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

A exibição indexada não corresponde

Explicação

A READPASTdica é semântica. O otimizador resiste à reescrita de consultas para que os resultados sejam alterados. Ilustrar:

A consulta a seguir é executada sem problemas:

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

Contudo:

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

Produz o erro:

Msg 8722, nível 16, estado 1, linha 42
Não é possível executar a consulta.
A dica semântica afetando 'readpast' aparece na cláusula 'WITH' do objeto 'VT'
mas não na cláusula correspondente 'TABLE HINT'.
Altere a cláusula OPTION (TABLE HINTS ...) para que as dicas que afetam a semântica
corresponda à cláusula WITH.

Quando você faz referência à exibição indexada sem a NOEXPANDdica, a exibição é expandida (antes do início da compilação e otimização) para fazer referência aos objetos subjacentes. Posteriormente no processo, o otimizador pode considerar corresponder a árvore de consultas a uma exibição indexada, no todo ou em parte.

Quando READPASTé usada sem NOEXPAND, a dica se propaga para a tabela base, impedindo a correspondência de exibição (semântica diferente).

Com NOEXPAND, a dica se aplica diretamente à visualização, portanto não há problema.

Paul White 9
fonte