MERGE utilizza tempdb?


12

Considera la seguente query:

MERGE [Parameter] with (rowlock) AS target
    USING (SELECT @AreaId, @ParameterTypeId, @Value)
            AS source (AreaId, ParameterTypeId, Value)
    ON (target.AreaId = source.AreaId AND 
        target.ParameterTypeId = source.ParameterTypeId)
    WHEN MATCHED THEN 
        UPDATE SET target.Value = source.Value, @UpdatedId = target.Id
    WHEN NOT MATCHED THEN
        INSERT ([AreaId], [ParameterTypeId], [Value])
        VALUES (source.AreaId, source.ParameterTypeId, source.Value);

L'I / O statistico fornisce il seguente output:

Tabella 'ParameterType'. Conteggio scansioni 0, letture logiche 2, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read lob iniziali 0.
Tabella "Area". Conteggio scansioni 0, letture logiche 2, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read lob iniziali 0.
Tabella "Parametro". Conteggio scansioni 1, letture logiche 4, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read lob iniziali 0.
Tabella 'Worktable'. Conteggio scansioni 1, letture logiche 0, letture fisiche 0, letture avanti 0, letture logiche lob 0, letture fisiche lob 0, letture read lob 0.

Worktable appare nella scheda Messaggi che mi fa pensare che tempdb sia utilizzato da MERGE.

Non vedo nulla nel piano di esecuzione che indichi la necessità di tempdb

Fa MERGEsempre utilizzare tempdb?

C'è qualcosa in BOL che spiega questo comportamento?

Usando INSERTe UPDATEsarebbe più veloce in questa situazione?

Sinistra

inserisci qui la descrizione dell'immagine

Giusto

inserisci qui la descrizione dell'immagine

Ecco la struttura della tabella

inserisci qui la descrizione dell'immagine


La bobina nel piano è un piano di lavoro in tempdb. Sembra strano che sia lì per una sola riga. Immagino che potrebbe essere lì per la protezione di Halloween.
Martin Smith,

Ora lo vedo. Memorizza i dati dall'input in una tabella temporanea al fine di ottimizzare i riavvolgimenti.
Craig Efrein,

Risposte:


8

(Espandendo il mio commento sulla domanda.)

Senza un vincolo univoco sulla combinazione di AreaIde ParameterTypeId, il codice dato è rotto perché @UpdatedId = target.Idregistrerà sempre e solo una singola riga Id.

A meno che tu non lo dica, SQL Server non può implicitamente conoscere i possibili stati dei dati. È necessario applicare il vincolo oppure, se più righe sono valide , sarà necessario modificare il codice per utilizzare un meccanismo diverso per generare i Idvalori.

A causa della possibilità che l'operatore di scansione rilevi più righe corrispondenti, la query deve richiedere lo spooling di tutte le corrispondenze per la protezione di Halloween. Come indicato nei commenti, il vincolo è valido, quindi aggiungerlo non cambierà solo il piano da una scansione a una ricerca, ma eliminerà anche la necessità dello spool della tabella, poiché SQL Server saprà che ci sarà 0 o 1 riga restituita dall'operatore di ricerca.


6

Se l'aggiornamento può modificare la posizione della riga nell'indice scansionato dall'aggiornamento, è necessario che SQL Server protegga dal problema di Halloween . Per questo SQL Server di solito inserisce uno spool della tabella desideroso nel piano di esecuzione subito dopo la scansione dell'indice. Questo operatore fondamentalmente crea una copia delle righe in questione e utilizza tempdb per questo.

La parte di aggiornamento dell'istruzione MERGE deve seguire le stesse regole e utilizza anche uno spool di tabella nella maggior parte dei casi in cui è richiesta la protezione di Halloween.

Anche se non riesco a capire se questo è il caso nella tua query, poiché non conosco le definizioni dell'indice, è molto probabile che cosa stia succedendo qui.

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.