MERGE utilise-t-il tempdb?

12

Considérez la requête suivante:

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);

Les E / S statistiques donnent la sortie suivante:

Tableau 'ParameterType'. Nombre de balayages 0, lectures logiques 2, lectures physiques 0, lectures anticipées 0, lectures logiques 0, lob lectures physiques 0, lob lectures anticipées 0.
Table 'Area'. Nombre de balayages 0, lectures logiques 2, lectures physiques 0, lectures anticipées 0, lectures logiques 0, lob lectures physiques 0, lob lectures anticipées 0.
Tableau 'Paramètre'. Nombre de balayages 1, lectures logiques 4, lectures physiques 0, lectures anticipées 0, lectures logiques 0, lob lectures physiques 0, lob lectures anticipées 0.
Tableau 'Table de travail'. Nombre de balayages 1, lectures logiques 0, lectures physiques 0, lectures anticipées 0, lectures logiques 0, lob lectures physiques 0, lob lectures anticipées 0.

La table de travail apparaît dans l'onglet messages, ce qui me fait penser que tempdb est utilisé par MERGE.

Je ne vois rien dans le plan d'exécution qui indiquerait un besoin de tempdb

Utilise MERGEtoujours tempdb?

Y a-t-il quelque chose dans BOL qui explique ce comportement?

Est-ce que l'utilisation INSERTet UPDATEserait plus rapide dans cette situation?

La gauche

entrez la description de l'image ici

Droite

entrez la description de l'image ici

Voici la structure du tableau

entrez la description de l'image ici

Craig Efrein
la source
La bobine du plan est une table de travail tempdb. Cela semble étrange qu'il soit là pour une seule rangée. Je suppose que cela peut être là pour la protection d'Halloween.
Martin Smith
Je le vois maintenant. Stocke les données de l'entrée dans une table temporaire afin d'optimiser les rembobinages.
Craig Efrein

Réponses:

8

(Développant mon commentaire sur la question.)

Sans une contrainte unique sur la combinaison de AreaIdet ParameterTypeId, le code donné est rompu car @UpdatedId = target.Idn'enregistrera jamais qu'une seule ligne Id.

Sauf si vous le dites, SQL Server ne peut pas implicitement connaître les états possibles des données. Soit la contrainte doit être appliquée, soit si plusieurs lignes sont valides , le code devra être modifié pour utiliser un mécanisme différent pour sortir les Idvaleurs.

En raison de la possibilité que l'opérateur d'analyse rencontre plusieurs lignes correspondantes, la requête doit mettre en attente toutes les correspondances pour la protection Halloween. Comme indiqué dans les commentaires, la contrainte est valide, donc l'ajouter non seulement changera le plan d'une analyse à une recherche, mais éliminera également le besoin du spouleur de table, car SQL Server saura qu'il y aura soit 0 ou 1 lignes renvoyées par l'opérateur de recherche.

Jon Seigel
la source
6

Si la mise à jour peut modifier la position de la ligne dans l'index analysé par la mise à jour, SQL Server doit se protéger du problème d'Halloween . Pour cela, SQL Server insère généralement un spool de table impatient dans le plan d'exécution juste après l'analyse d'index. Cet opérateur crée essentiellement une copie des lignes en question et utilise tempdb pour cela.

La partie mise à jour de l'instruction MERGE doit suivre les mêmes règles et utilise également une bobine de table dans la plupart des cas où la protection Halloween est requise.

Bien que je ne puisse pas dire si c'est le cas dans votre requête, car je ne connais pas la ou les définitions d'index, c'est probablement ce qui se passe ici.

Sebastian Meine
la source