Perché il suggerimento READPAST fa ignorare le viste indicizzate?


10

Sto studiando utilizzando il READPASTsuggerimento per ridurre il blocco delle risorse nel sottosistema finanziario della nostra applicazione.

Sembrava una buona strada da percorrere perché i record delle transazioni finanziarie vengono sempre aggiunti, mai aggiornati o eliminati. Le uniche righe che verrebbero mai ignorate sono le nuovissime righe inserite all'interno di una transazione; in effetti non esistono nel mondo esterno fino a quando la transazione non viene impegnata.

Tuttavia, ho notato prestazioni peggiori nelle query che utilizzano viste indicizzate su cui avevo messo il READPASTsuggerimento. Confrontando i piani di query, sembra che con il suggerimento, Query Optimizer sceglie di non utilizzare la vista indicizzata e invece ricorre a trattarla come una vista normale.

Non sono sicuro del perché; Immagino che le viste indicizzate siano come qualsiasi altro indice in quanto le chiavi possono essere bloccate durante le operazioni e l'aggiunta READPASTfunzionerebbe in modo simile.

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

inserisci qui la descrizione dell'immagine

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

inserisci qui la descrizione dell'immagine

Anche l'aggiunta di un NOEXPANDsuggerimento sembra funzionare, ma sono interessato a saperne di più sul possibile motivo per cui READPASTl'ottimizzatore delle query ha fatto questa scelta in primo luogo (come parte di una risposta completa).

Risposte:


7

Riutilizzo della tabella di esempio e della vista indicizzata dal mio articolo Un altro motivo per utilizzare i NOEXPANDsuggerimenti in 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

Questa query corrisponde alla vista indicizzata (sebbene con un aggregato ridondante):

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

Vista indicizzata abbinata

L'aggiunta di un READPASTsuggerimento comporta l'accesso alla tabella di base:

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

Vista indicizzata non corrispondente

Spiegazione

Il READPASTsuggerimento ha effetti semantici. L'ottimizzatore resiste alla riscrittura delle query in modo che i risultati cambino. Illustrare:

La seguente query viene eseguita senza problemi:

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

Tuttavia:

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

Produce l'errore:

Messaggio 8722, livello 16, stato 1, linea 42
Impossibile eseguire la query.
Il suggerimento semantico che influenza 'readpast' appare nella clausola 'WITH' dell'oggetto 'VT'
ma non nella corrispondente clausola "TABLE HINT".
Modificare la clausola OPTION (TABLE HINTS ...) in modo che i suggerimenti semantici influenzino
corrisponde alla clausola WITH.

Quando si fa riferimento alla vista indicizzata senza il NOEXPANDsuggerimento, la vista viene espansa (prima che inizi la compilazione e l'ottimizzazione) per fare riferimento invece agli oggetti sottostanti. Più avanti nel processo, l'ottimizzatore potrebbe prendere in considerazione la possibilità di far corrispondere l'albero delle query a una vista indicizzata, in tutto o in parte.

Se READPASTutilizzato senza NOEXPAND, il suggerimento si propaga alla tabella di base, impedendo la corrispondenza della vista (semantica diversa).

Con NOEXPAND, il suggerimento si applica direttamente alla vista, quindi non ci sono problemi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.