Considere a seguinte consulta:
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);
E / S de estatísticas fornece a seguinte saída:
Tabela 'ParameterType'. Contagem de varreduras 0, leituras lógicas 2, leituras físicas 0, leituras de leitura antecipada 0, leituras lógicas de lob 0, leituras físicas de lob 0, leituras físicas de lob 0, leituras de leitura antecipada de 0.
Tabela 'Área'. Contagem de varreduras 0, leituras lógicas 2, leituras físicas 0, leituras de leitura antecipada 0, leituras lógicas de lob 0, leituras físicas de lob 0, leituras físicas de lob 0, leituras de leitura antecipada de 0.
Tabela 'Parâmetro'. Contagem de varredura 1, leituras lógicas 4, leituras físicas 0, leituras de leitura antecipada 0, leituras lógicas de lob 0, leituras físicas de lob 0, leituras físicas de lob 0, leituras de leitura antecipada de lob 0.
Tabela 'Worktable'. Contagem de varreduras 1, leituras lógicas 0, leituras físicas 0, leituras de leitura antecipada 0, leituras lógicas de lob 0, leituras físicas de lob 0, leituras físicas de lob 0, leituras de leitura antecipada de lob 0.
A tabela de trabalho aparece na guia Mensagens, o que me faz pensar que o tempdb está sendo usado pelo MERGE
.
Não estou vendo nada no plano de execução que indique a necessidade de tempdb
Será MERGE
sempre usar tempdb?
Existe algo no BOL que explique esse comportamento?
Usar INSERT
e UPDATE
ser mais rápido nessa situação?
Esquerda
Certo
Aqui está a estrutura da tabela
fonte
tempdb
. Parece estranho que ele esteja lá por uma única linha. Eu acho que pode estar lá para a proteção do Halloween.Respostas:
(Expandindo meu comentário sobre a pergunta.)
Sem uma restrição exclusiva na combinação de
AreaId
eParameterTypeId
, o código fornecido é quebrado porque@UpdatedId = target.Id
apenas registrará uma única linhaId
.A menos que você diga, o SQL Server não pode saber implicitamente os possíveis estados dos dados. A restrição deve ser imposta ou, se várias linhas forem válidas , o código precisará ser alterado para usar um mecanismo diferente para gerar os
Id
valores.Devido à possibilidade de o operador de varredura encontrar várias linhas correspondentes, a consulta deve colocar em spool todas as correspondências para proteção de Halloween. Conforme indicado nos comentários, a restrição é válida, portanto, adicioná-la não apenas mudará o plano de uma varredura para uma busca, mas também eliminará a necessidade do spool de tabela, pois o SQL Server saberá que haverá 0 ou 0 1 linhas retornadas do operador de busca.
fonte
Se a atualização puder alterar a posição da linha no índice verificado pela atualização, o SQL Server precisará se proteger do Problema do Dia das Bruxas . Para isso, o SQL Server geralmente insere um spool de tabela ansioso no plano de execução logo após a verificação do índice. Esse operador basicamente cria uma cópia das linhas em questão e usa tempdb para isso.
A parte de atualização da instrução MERGE precisa seguir as mesmas regras e também usa um spool de tabela na maioria dos casos em que a Proteção de Halloween é necessária.
Embora eu não possa dizer se esse é o caso da sua consulta, como não conheço as definições de índice, é mais provável que isso esteja acontecendo aqui.
fonte