Question

Quels sont les avantages, le cas échéant, de faire explicitement une jointure HASH par rapport à une jointure standard (dans laquelle SQL Server décidera de la meilleure stratégie de jointure)? Par exemple:

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

Dans l'exemple de code simpliste ci-dessus, je spécifie la stratégie JOIN, alors que si je laisse le "hash" " Le mot clé SQL Server effectuera un MERGE JOIN en coulisse (selon le "plan d'exécution réel").

Était-ce utile?

La solution

L’optmiser fait un travail suffisant pour un usage quotidien. Cependant, en théorie, il peut prendre 3 semaines pour trouver le plan idéal à l'extrême, il est donc possible que le plan généré ne soit pas idéal.

Je le laisserais tranquille à moins que votre requête soit très complexe ou que vous ne disposiez d'énormes quantités de données qui ne permettent tout simplement pas de produire un bon plan. Alors je le considérerais.

Mais avec le temps, à mesure que les données changent / s'agrandissent ou que les index changent, etc., votre indicateur JOIN devient obsolète et empêche un plan optimal. Un indicateur JOIN ne peut optimiser que pour cette requête unique au moment du développement avec cet ensemble de données.

Personnellement, je n'ai jamais spécifié d'indicateur JOIN dans aucun code de production.

En règle générale, j'ai résolu une mauvaise jointure en modifiant ma requête, en ajoutant / modifiant un index ou en le décomposant (par exemple, chargez d'abord une table temporaire). Ou ma requête était tout simplement fausse, ou j'avais une conversion implicite de type de données, ou elle mettait en évidence une faille dans mon schéma, etc.

J'ai vu d'autres développeurs les utiliser, mais uniquement dans les cas où leurs vues complexes étaient imbriquées dans des vues complexes et qui posaient des problèmes lors de leur refactorisation.

Modifier:

J'ai eu une conversion aujourd'hui où certains collègues vont l'utiliser pour forcer un plan de requête incorrect (avec NOLOCK et MAXDOP 1) à "encourager" migration de vues héritées complexes héritées qu'un de leurs systèmes en aval appelle directement.

Autres conseils

Quand essayer un indice de hachage, que diriez-vous:

  • Après avoir vérifié que des index adéquats existent sur au moins un des tables.
  • Après avoir tenté de réorganiser la requête. Des choses comme la conversion se joint à " dans " ou "existe", modification de l'ordre de jointure (qui n'est en réalité qu'un de toute façon), déplacement de la logique de la clause where à la condition de jointure, etc.

Certaines règles de base concernant le moment auquel une jointure de hachage est effective sont spécifiées lorsqu'une condition de jointure n'existe pas sous forme d'index de table et que la taille des tables est différente. Si vous recherchez une description technique, il existe de bonnes descriptions sur le fonctionnement d’une jointure de hachage.

Pourquoi utiliser des indications de jointure (hachage / fusion / boucle avec effet secondaire d'ordre de force)?

  • Pour éviter une exécution extrêmement lente (0,5 - & 10.0s) des cas de coin.
  • Lorsque l'optimiseur choisit systématiquement un plan médiocre.

Un indice fourni est susceptible de ne pas être idéal dans certaines circonstances, mais fournit des durées d’exécution plus prévisibles. Les scénarios les plus défavorables et optimaux prévus devraient être pré-testés lors de l'utilisation d'un indice. Des durées d’exécution prévisibles sont essentielles pour les services Web, dans lesquels une requête nominale [.3s, 0.6s] rigoureusement optimisée est préférable à une requête pouvant aller de [0,25, 10,0s] par exemple. Des écarts importants peuvent survenir avec les statistiques récemment mises à jour et les meilleures pratiques suivies.

Lors des tests dans un environnement de développement, désactivez l'option "tricherie". ainsi pour éviter les écarts de durée d’exécution chaud / froid. Dans un autre post ...

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

La dernière option peut être identique à l'indicateur d'option (recompiler).

Le MAXDOP et le chargement de la machine peuvent également faire une énorme différence en termes d’exécution. La matérialisation de CTE dans les tables de temp est également un bon mécanisme de verrouillage et une chose à considérer.

Les jointures de hachage parallélisent et évoluent mieux que toute autre jointure et permettent de maximiser le débit des entrepôts de données.

Le seul indice que j'ai jamais vu dans le code d'expédition était OPTION (FORCE ORDER). Un bogue stupide dans l'optimiseur de requête SQL générerait un plan qui tenterait de joindre un varchar non filtré et un identifiant unique. L’ajout de FORCE ORDER lui a permis d’exécuter d’abord le filtre.

Je sais, surcharger les colonnes est une mauvaise chose. Parfois, il faut vivre avec.

L’optimiseur de planification logique ne vous garantit pas qu’il trouve la solution optimale: un algorithme exact est trop lent pour être utilisé sur un serveur de production; à la place, des algorithmes gloutons sont utilisés.

Par conséquent, le but de ces commandes est de permettre à l'utilisateur de spécifier la stratégie de jointure optimale, au cas où l'optimiseur ne pourrait pas déterminer ce qu'il y a de mieux à adopter.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top