OPTION FORCE ORDER améliore les performances jusqu'à la suppression des lignes


9

J'ai une requête SQL Server 2008 quelque peu complexe (environ 200 lignes de SQL assez dense) qui ne fonctionnait pas comme j'en avais besoin. Au fil du temps, les performances sont passées d'environ 0,5 seconde à environ 2 secondes.

En examinant le plan d'exécution, il était assez évident qu'en réorganisant les jointures, les performances pouvaient être améliorées. Je l'ai fait, et ça l'a fait ... jusqu'à environ 0,3 seconde. Maintenant, la requête a l'indication "OPTION FORCE ORDER" et la vie est bonne.

Je viens aujourd'hui pour nettoyer la base de données. J'archive environ 20% des lignes, sans aucune action dans la base de données concernée, sauf la suppression des lignes ... le plan d'exécution est TOTALEMENT arrosé . Il évalue complètement le nombre de lignes que certains sous-arbres retourneront, et (par exemple) remplace a:

<Hash>

avec

<NestedLoops Optimized='false' WithUnorderedPrefetch='true'>

Maintenant, le temps de requête passe d'environ 0,3 s à environ 18 s. (!) Tout simplement parce que j'ai supprimé des lignes. Si je supprime l'indice de requête, je reviens à environ 2 secondes de temps de requête. Mieux, mais pire.

J'ai reproduit le problème après avoir restauré la base de données sur plusieurs emplacements et serveurs. La simple suppression d'environ 20% des lignes de chaque table entraîne toujours ce problème.

  1. Est-ce normal qu'un ordre de jointure forcée rende les estimations de requête complètement inexactes (et donc les temps de requête imprévisibles)?
  2. Dois-je simplement m'attendre à devoir accepter des performances de requête sous-optimales ou à les regarder comme un faucon et à modifier fréquemment les conseils de requête manuellement? Ou peut-être aussi faire allusion à chaque jointure? .3s à 2s est un gros coup à prendre.
  3. Est-il évident pourquoi l'optimiseur a explosé après la suppression de lignes? Par exemple, "oui, il a fallu une analyse d'échantillon, et parce que j'ai archivé la plupart des lignes plus tôt dans l'historique des données, l'échantillon a donné des résultats clairsemés, donc il a sous-estimé la nécessité d'une opération de hachage triée"?

Si vous souhaitez voir les plans d'exécution, veuillez suggérer un emplacement où je peux les publier. Sinon, j'ai échantillonné le morceau le plus étonnant. Voici l'erreur fondamentale d'estimation, les nombres en parenthèses sont des lignes (estimées: réelles).

                             /  Clustered Index Scan (908:7229)
Nested Loops (Inner Join) --<
                             \  NonClustered Index Seek (1:7229)

Notez que la boucle intérieure devrait balayer 908 lignes, mais balaye à la place 52 258 441. Si elle avait été exacte, cette branche aurait fonctionné environ 2 ms, au lieu de 12 secondes. Avant de supprimer les lignes, cette estimation de jointure interne n'était désactivée que par un facteur total de 2 et a été effectuée en tant que correspondance de hachage sur deux index clusterisés.

Réponses:


6

Est-ce normal qu'un ordre de jointure forcée rende les estimations de requête complètement inexactes (et donc les temps de requête imprévisibles)?

L'utilisation de FORCE ORDER ne rend pas les estimations inexactes, la suppression des lignes l'a fait. Forcer une mise à jour des statistiques sur la table peut améliorer la précision de l'estimation.

Dois-je simplement m'attendre à devoir accepter des performances de requête sous-optimales ou à les regarder comme un faucon et à modifier fréquemment les conseils de requête manuellement? Ou peut-être aussi faire allusion à chaque jointure? .3s à 2s est un gros coup à prendre.

Il serait préférable de s'assurer que l'optimiseur reçoit les informations dont il a besoin pour générer le meilleur plan, sans utiliser l'indication FORCE ORDER. Ce faisant, il devrait mieux gérer les modifications de la distribution des données sous-jacentes sans nécessiter d'intervention manuelle. Cela dit, si la nature des données est telle que la cardinalité peut varier considérablement d'heure en heure ou de jour en heure, envisagez d'utiliser un guide de plan pour vous assurer que le plan est fixe.

Est-il évident pourquoi l'optimiseur a explosé après la suppression de lignes? Par exemple, "oui, il a fallu une analyse d'échantillon, et parce que j'ai archivé la plupart des lignes plus tôt dans l'historique des données, l'échantillon a donné des résultats clairsemés, donc il a sous-estimé la nécessité d'une opération de hachage triée"?

Vous n'avez pas mentionné le nombre de lignes dans les tables de problèmes, mais il est probable que les suppressions:

  • n'a pas supprimé suffisamment de lignes pour déclencher une mise à jour des statistiques. Cela devrait se produire lorsque 20% des lignes ont été modifiées, mais il est possible d'utiliser l' indicateur de trace 2371 pour activer un seuil dynamique.
  • a déclenché une mise à jour des statistiques mais l'échantillon recueilli n'était pas représentatif. Corrigez cela en exécutant une mise à jour manuelle AVEC FULLSCAN .

Vous pouvez également rencontrer de bons problèmes de reniflage de paramètres à l' ancienne , pour lesquels il existe une myriade d'options pour contourner. WITH RECOMPILE peut être une option coûteuse pour spécifier une requête de cette taille, mais cela vaut la peine d'enquêter au niveau de la procédure et de l'instruction.


Juste une clarification, c'est probablement de la sémantique: "L'utilisation de FORCE ORDER ne rend pas les estimations inexactes, la suppression des lignes l'a fait." Donc, vous pensez que c'est juste une chance aléatoire que la suppression de "FORCE ORDER" améliore tellement la requête? L'astuce n'a pas poussé l'optimiseur à s'appuyer sur des statistiques sur lesquelles il mettrait moins l'accent, ou n'a pas été découvert dans le test d'application, car cette statistique moins fiable était rarement cruciale?
shannon

Je pense que oui, dans la mesure où le choix de plan préféré des optimiseurs se trouve être confronté à des statistiques inexactes, mais le plan résultant de l'ordre de jointure forcé ne le fait pas. Je ne suis pas au courant de FORCE ORDER provoquant un changement dans l'évaluation des statistiques, quelqu'un d'autre interviendra s'il sait quelque chose du contraire. Vous devez également déterminer si la valeur que vous avez choisie pour OPTIMISER POUR est appropriée. Il se peut que les statistiques soient tout à fait correctes mais vous forcez un plan basé sur une valeur qui n'est pas représentative.
Mark Storey-Smith

Droite. J'ai le même problème de performances en passant les paramètres exactement comme je les ai optimisés. Merci encore.
shannon
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.