Pregunta

¿Cuáles son las ventajas, si las hay, de hacer explícitamente un HASH JOIN sobre un JOIN regular (en el que SQL Server decidirá la mejor estrategia de JOIN)? Por ejemplo:

select pd.*
from profiledata pd
inner hash join profiledatavalue val on val.profiledataid=pd.id

En el código de ejemplo simplista de arriba, estoy especificando la estrategia de UNIR, mientras que si omito el " hash " la palabra clave SQL Server realizará una COMBINACIÓN MERGE entre bambalinas (según el "plan de ejecución real").

¿Fue útil?

Solución

El optmiser hace un trabajo suficientemente bueno para el uso diario. Sin embargo, en teoría, podría necesitar 3 semanas para encontrar el plan perfecto en el extremo, por lo que existe la posibilidad de que el plan generado no sea el ideal.

Lo dejaría solo a menos que tenga una consulta muy compleja o grandes cantidades de datos donde simplemente no puede producir un buen plan. Entonces lo consideraría.

Pero a lo largo del tiempo, a medida que los datos cambian / crecen o los índices cambian, etc., su sugerencia de ÚNETE se volverá obsoleta e impedirá un plan óptimo. Una sugerencia ÚNICA solo puede optimizar esa única consulta en el momento del desarrollo con el conjunto de datos que tiene.

Personalmente, nunca he especificado una sugerencia de ÚNETE en ningún código de producción.

Normalmente, resolví una unión incorrecta cambiando mi consulta, agregando / cambiando un índice o dividiéndolo (por ejemplo, cargar una tabla temporal primero). O mi consulta fue incorrecta, o tuve una conversión de tipo de datos implícita, o resaltó un defecto en mi esquema, etc.

He visto que otros desarrolladores los usan, pero solo donde tenían vistas complejas anidadas en vistas complejas y causaron problemas posteriores cuando se volvieron a redactar.

Editar:

Hoy tuve una conversión en la que algunos colegas los usarán para forzar un plan de consulta erróneo (con NOLOCK y MAXDOP 1) para " alentar " la migración se aleja de las vistas anidadas complejas heredadas que uno de sus sistemas descendentes llama directamente.

Otros consejos

Cuándo intentar una sugerencia de hash, ¿qué hay de:

  • Después de verificar que existen índices adecuados en al menos uno de los mesas.
  • Después de haber intentado reorganizar la consulta. Cosas como convertir se une a " en " o " existe " cambiando el orden de unión (que es solo un pista de todos modos), moviendo la lógica desde donde cláusula para unirse condición, etc.

Algunas reglas básicas sobre cuándo es efectiva una combinación hash es cuando una condición de unión no existe como un índice de tabla y cuando los tamaños de las tablas son diferentes. Si buscas una descripción técnica, hay algunas buenas descripciones sobre cómo funciona una combinación hash.

¿Por qué usar cualquier sugerencia de combinación (hash / merge / loop con efecto secundario de orden de fuerza)?

  • Para evitar la ejecución extremadamente lenta (.5 - > 10.0s) de casos de esquina.
  • Cuando el optimizador elige constantemente un plan mediocre.

Es probable que una sugerencia proporcionada no sea ideal para algunas circunstancias, pero proporciona tiempos de ejecución predecibles de manera más consistente. Los escenarios de peor caso esperado y mejor caso deben probarse previamente cuando se utiliza una sugerencia. Los tiempos de ejecución predecibles son críticos para los servicios web en los que se prefiere una consulta nominal [.3s, .6s] rígidamente optimizada sobre una que puede oscilar entre [.25, 10.0s], por ejemplo. Pueden ocurrir grandes variaciones en el tiempo de ejecución con estadísticas actualizadas y las mejores prácticas seguidas.

Al realizar pruebas en un entorno de desarrollo, uno debe desactivar " hacer trampa " También para evitar variaciones en el frío / calor. De otro post ...

CHECKPOINT -- flushes dirty pages to disk
DBCC DROPCLEANBUFFERS -- clears data cache
DBCC FREEPROCCACHE -- clears execution plan cache

La última opción puede ser la misma que la opción (recompilar).

El MAXDOP y la carga de la máquina también pueden marcar una gran diferencia en el tiempo de ejecución. La materialización de CTE en tablas temporales también es un buen mecanismo de bloqueo y algo a tener en cuenta.

Las combinaciones hash se paralizan y escalan mejor que cualquier otra combinación y son excelentes para maximizar el rendimiento en los almacenes de datos.

La única pista que he visto en el código de envío fue OPCIÓN (ORDEN DE FUERZA). Un error estúpido en el optimizador de consultas SQL generaría un plan que intentaba unir una varchar sin filtrar y un identificador único. La adición de FORCE ORDER provocó que ejecutara el filtro primero.

Lo sé, sobrecargar columnas es malo. A veces, tienes que vivir con eso.

El optimizador de plan lógico no le asegura que encuentre la solución óptima: un algoritmo exacto es demasiado lento para usar en un servidor de producción; en su lugar, se utilizan algunos algoritmos codiciosos.

Por lo tanto, la razón detrás de estos comandos es permitir que el usuario especifique la estrategia de unión óptima, en el caso de que el optimizador no pueda determinar qué es lo mejor que puede adoptar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top