Ordenar derrames a tempdb pero las filas estimadas son iguales a las filas reales


14

En un SQL Server 2016 SP2 con memoria máxima establecida en 25 GB, tenemos una consulta que se ejecuta aproximadamente 80 veces en un minuto. La consulta derrama alrededor de 4000 páginas a tempdb. Esto provoca una gran cantidad de E / S en el disco de tempdb.

Cuando eche un vistazo al plan de consulta (consulta simplificada) verá que la cantidad de filas estimadas es igual a la cantidad de filas reales, pero aún se producen derrames. Por lo tanto, las estadísticas desactualizadas no pueden ser la causa del problema.

Hice algunas pruebas y derrames de consultas a Tempdb:

select id --uniqueidentifier
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)

Pero si selecciono una columna diferente no se producen derrames:

select startdate --datetime
from SortProblem
where [status] ='A'
order by SequenceNumber asc 
option (maxdop 1)

Así que traté de 'agrandar' el tamaño de la columna de identificación:

select CONVERT(nvarchar(512),id)
from SortProblem
where [status] ='A'
order by SequenceNumber asc 
option (maxdop 1)

Entonces tampoco se produce derrame.

¿Por qué se derrama el identificador único a tempdb y no a una columna datatime? Cuando elimino alrededor de 20000 registros, tampoco ocurre ningún derrame cuando selecciono la columna id.

Con el siguiente script puede reproducir el problema:

CREATE TABLE SortProblem
  (
     id             UNIQUEIDENTIFIER,
     startdate      DATETIME,
     sequencenumber BIGINT,
     status         VARCHAR(50),
     PRIMARY KEY CLUSTERED(id)
  )

SET nocount ON;

WITH nums(num)
     AS (SELECT TOP 103000 ROW_NUMBER()
                             OVER (
                               ORDER BY 1/0)
         FROM   sys.all_objects o1,
                sys.all_objects o2)
INSERT INTO SortProblem
SELECT newid(),
       DATEADD(millisecond, num, GETDATE()),
       num,
       CASE
         WHEN num <= 100000 THEN 'A'
         WHEN num <= 101000 THEN 'B'
         WHEN num <= 102000 THEN 'C'
         WHEN num <= 103000 THEN 'D'
       END
FROM   nums

CREATE NONCLUSTERED INDEX [IX_Status]
  ON [dbo].[SortProblem]([status] ASC)
  INCLUDE ([sequencenumber]) 

Respuestas:


14

Habilite el indicador de rastreo 7470.

REVISIÓN: Ordenar los derrames del operador a tempdb en SQL Server 2012 o SQL Server 2014 cuando el número estimado de filas y el tamaño de fila son correctos

Como escribí en respuesta a la pregunta del plan de consulta :

Este indicador de seguimiento corrige un descuido en el cálculo. Es bastante seguro de usar y, en mi opinión, debería estar activado de forma predeterminada. El cambio está protegido por una marca de seguimiento simplemente para evitar cambios inesperados en el plan.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.