¿Por qué es tan alto el número de ejecuciones del análisis de índice agrupado?

15

Tengo dos consultas similares que generan el mismo plan de consulta, excepto que un plan de consulta ejecuta un Análisis de índice agrupado 1316 veces, mientras que el otro lo ejecuta 1 vez.

La única diferencia entre las dos consultas es un criterio de fecha diferente. La consulta de larga duración en realidad limita los criterios de fecha y extrae menos datos.

He identificado algunos índices que ayudarán con ambas consultas, pero solo quiero entender por qué el operador de exploración de índice agrupado se está ejecutando 1316 veces en una consulta que es prácticamente la misma que la que se ejecuta 1 vez.

Verifiqué las estadísticas del PK que se está escaneando y están relativamente actualizadas.

Consulta original:

select distinct FIR_Incident.IncidentID
from FIR_Incident
left join (
    select incident_id as exported_incident_id
    from postnfirssummary
) exported_incidents on exported_incidents.exported_incident_id = fir_incident.incidentid
where FI_IncidentDate between '2011-06-01 00:00:00.000' and '2011-07-01 00:00:00.000'
    and exported_incidents.exported_incident_id is not null

Genera este plan: ingrese la descripción de la imagen aquí

Después de reducir los criterios del intervalo de fechas:

select distinct FIR_Incident.IncidentID
from FIR_Incident
left join (
    select incident_id as exported_incident_id
    from postnfirssummary
) exported_incidents on exported_incidents.exported_incident_id = fir_incident.incidentid
where FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'
    and exported_incidents.exported_incident_id is not null

Genera este plan: ingrese la descripción de la imagen aquí

Seibar
fuente
¿Podría copiar / pegar sus consultas en un bloque de código en lugar de archivos de imagen?
Eric Humphrey - lotsahelp
Claro, agregué las consultas que generan cada plan.
Seibar
¿En qué tabla está ocurriendo la exploración de índice agrupado?
Eric Humphrey - lotsahelp
El escaneo de índice agrupado está en la subconsulta en la unión izquierda (PostNFIRSSummary)
Seibar
1
Presumiblemente la última vez que se actualizaron las estadísticas, solo había cero o una fila que cumpliera con los FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'criterios y desde entonces ha habido un número desproporcionado de inserciones en ese rango. Estima que solo se necesitarán 1.07 ejecuciones para ese rango de fechas. No los 1.316 que se producen en la actualidad.
Martin Smith

Respuestas:

9

La UNIÓN después de la exploración da una pista: con menos filas en un lado de la última unión (leyendo de derecha a izquierda, por supuesto), el optimizador elige un "bucle anidado", no una "unión hash".

Sin embargo, antes de ver esto, mi objetivo sería eliminar la búsqueda de claves y el DISTINCT.

  • Búsqueda clave: su índice en FIR_Incident debería estar cubriendo, probablemente (FI_IncidentDate, incidentid)o al revés. O tenga ambos y vea cuál se usa con más frecuencia (ambos pueden serlo)

  • El DISTINCTes una consecuencia de la LEFT JOIN ... IS NOT NULL. El optimizador ya lo ha eliminado (los planes han "dejado semiuniones" en la ÚNICA final) pero usaría EXISTA para mayor claridad

Algo como:

select 
    F.IncidentID
from 
    FIR_Incident F
where 
    exists (SELECT * FROM postnfirssummary P
           WHERE P.incident_id = F.incidentid)
    AND
    F.FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'

También puede usar guías de plan y sugerencias JOIN para hacer que SQL Server use una combinación hash, pero intente que funcione normalmente primero: una guía o una sugerencia probablemente no resistirán la prueba del tiempo porque solo son útiles para los datos y consultas que ejecuta ahora, no en el futuro

gbn
fuente