Tengo una consulta que une algunas tablas y funciona bastante mal: las estimaciones de fila están muy lejos (1000 veces) y se elige la unión de bucles anidados, lo que da como resultado múltiples escaneos de tabla. La forma de la consulta es bastante sencilla, se parece a esto:
SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id
WHERE t4.id = some_GUID
Jugando con la consulta, noté que cuando le sugiero que use una combinación de combinación para una de las combinaciones, se ejecuta muchas veces más rápido. Esto lo puedo entender: la combinación de combinación es una mejor opción para los datos que se unen, pero SQL Server simplemente no estima que es correcto elegir los bucles anidados.
Lo que no entiendo completamente es por qué esta sugerencia de combinación cambia todas las estimaciones para todos los operadores del plan. Al leer diferentes artículos y libros, asumí que las estimaciones de cardinalidad se realizan antes de que se construya el plan, por lo que el uso de una sugerencia no habría cambiado las estimaciones, sino que explícitamente le dijera a SQL Server que use una implementación de unión física particular.
Sin embargo, lo que veo es que la sugerencia de combinación hace que todas las estimaciones se vuelvan prácticamente perfectas. ¿Por qué sucede esto? ¿Existen técnicas comunes para hacer que el optimizador de consultas haga una mejor estimación sin una sugerencia, teniendo en cuenta que las estadísticas obviamente lo permiten?
UPD: los planes de ejecución anónimos se pueden encontrar aquí: https://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl=0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hints_join.sqlplan?dl = 0
Verifiqué las estadísticas utilizadas por ambas consultas usando TF 3604, 9292 y 9204, y son idénticas. Sin embargo, los índices que se escanean / buscan difieren entre las consultas.
Además de eso, intenté ejecutar la consulta con OPTION (FORCE ORDER)
: se ejecuta incluso más rápido que con la combinación de combinación, eligiendo HASH MATCH para cada combinación.