Considere la siguiente 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);
La E / S estadística proporciona el siguiente resultado:
Tabla 'ParameterType'. Cuenta de escaneo 0, lecturas lógicas 2, lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas lob de lectura anticipada 0.
Tabla 'Área'. Cuenta de escaneo 0, lecturas lógicas 2, lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas lob de lectura anticipada 0.
Tabla 'Parámetro'. Cuenta de escaneo 1, lecturas lógicas 4, lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas lob de lectura anticipada 0.
Tabla 'Mesa de trabajo'. Recuento de escaneo 1, lecturas lógicas 0, lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas de lectura lob 0.
La tabla de trabajo aparece en la pestaña de mensajes, lo que me hace pensar que tempdb está siendo utilizado por MERGE
.
No veo nada en el plan de ejecución que indique una necesidad de tempdb
¿ MERGE
Siempre usa tempdb?
¿Hay algo en BOL que explique este comportamiento?
¿Usaría INSERT
& UPDATE
sería más rápido en esta situación?
Izquierda
Derecho
Aquí está la estructura de la tabla.
fuente
tempdb
. Sin embargo, parece extraño que esté allí para una sola fila. Supongo que puede estar allí para la protección de Halloween.Respuestas:
(Ampliando mi comentario sobre la pregunta).
Sin una restricción única en la combinación de
AreaId
yParameterTypeId
, el código dado se rompe porque@UpdatedId = target.Id
solo registrará una sola filaId
.A menos que lo indique, SQL Server no puede conocer implícitamente los posibles estados de los datos. O bien, la restricción debe aplicarse, o si varias filas son válidas , el código deberá cambiarse para usar un mecanismo diferente para generar los
Id
valores.Debido a la posibilidad de que el operador de exploración se encuentre con varias filas coincidentes, la consulta debe poner en espera todas las coincidencias para la protección de Halloween. Como se indica en los comentarios, la restricción es válida, por lo que agregarla no solo cambiará el plan de una exploración a una búsqueda, sino que también eliminará la necesidad del carrete de tabla, ya que SQL Server sabrá que habrá 0 o 1 filas devueltas desde el operador de búsqueda.
fuente
Si la actualización puede cambiar la posición de la fila en el índice escaneado por la actualización, SQL Server debe protegerse del problema de Halloween . Para eso, SQL Server generalmente inserta un spool de tabla ansioso en el plan de ejecución justo después de la exploración del índice. Ese operador básicamente crea una copia de las filas en cuestión y usa tempdb para eso.
La parte de actualización de la declaración MERGE tiene que seguir las mismas reglas y también usa un carrete de mesa en la mayoría de los casos donde se requiere la protección de Halloween.
Si bien no puedo decir si este es el caso en su consulta, ya que no sé las definiciones de índice, es muy probable que esto esté sucediendo aquí.
fuente