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 MERGE
toujours tempdb?
Y a-t-il quelque chose dans BOL qui explique ce comportement?
Est-ce que l'utilisation INSERT
et UPDATE
serait plus rapide dans cette situation?
La gauche
Droite
Voici la structure du tableau
la source
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.Réponses:
(Développant mon commentaire sur la question.)
Sans une contrainte unique sur la combinaison de
AreaId
etParameterTypeId
, le code donné est rompu car@UpdatedId = target.Id
n'enregistrera jamais qu'une seule ligneId
.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
Id
valeurs.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.
la source
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.
la source