2009-01-21 4 views
5

Aujourd'hui encore, j'ai un problème MAJEUR avec ce qui semble être reniflage de paramètres dans SQL Server 2005.À un moment donné de votre carrière avec SQL Server, est-ce que le reniflage de paramètre saute et attaque?

J'ai une requête comparant certains résultats avec de bons résultats connus. J'ai ajouté une colonne aux résultats et les bons résultats connus, de sorte que chaque mois, je peux charger un nouveau mois de résultats des deux côtés et de comparer uniquement le mois en cours. La nouvelle colonne est la première dans l'index clusterisé, de sorte que les nouveaux mois vont ajouter à la fin.

-je ajouter un critère à mon WHERE article - ce qui est généré par le code, il est donc une constante littérale:

WHERE DATA_DT_ID = 20081231 - Ce qui est redondant parce que tous sont DATA_DT_ID 20.081.231 en ce moment.

Les performances vont au pot. De 7 secondes pour comparer environ 1.5m lignes à 2 heures et rien de terminer. Exécution du droit SQL généré dans SSMS - pas de SP. J'ai utilisé SQL Server depuis 12 ans maintenant et je n'ai jamais eu autant de problèmes avec le reniflage de paramètres que j'ai eu sur ce serveur de production depuis octobre (build build 9.00.3068.00). Et dans tous les cas, ce n'est pas parce qu'il a été exécuté la première fois avec un paramètre différent ou que la table a été modifiée. Ceci est une nouvelle table et il est exécuté uniquement avec ce paramètre ou aucune clause WHERE.

Et, non, je n'ai pas accès DBA, et ils ne m'ont pas donné assez de droits pour voir les plans d'exécution.

Au point où je ne suis pas sûr de pouvoir gérer ce système avec les utilisateurs de SQL Server avec seulement quelques années d'expérience.

MISE À JOUR Il s'avère que, bien que les statistiques prétendent être à jour, l'exécution de UPDATE STATISTICS WITH FULLSCAN résout le problème.

MISE A JOUR FINAL Même avec recréer la SP, en utilisant des statistiques de recompiler et UPDATE, il est apparu la requête devait être réécrite d'une manière différente d'utiliser un PAS au lieu d'un LEFT JOIN avec contrôle NULL.

+0

Y a-t-il une question ici? Ça sonne comme un reproche, votre clause où n'utilise pas de paramètres – JoshBerke

+0

Oui, les questions sont pourquoi après toutes ces années je suis confronté à ces problèmes tout le temps maintenant - je pense que la réponse est que sur ce serveur les statistiques ne sont pas gérées comme mes propres serveurs normalement ou comme mes serveurs de développement et de test sont. –

+0

Je crois comprendre que c'est fondamentalement le même problème.Les constantes sont paramétrées et les plans d'exécution construits en fonction des estimations de lignes attendues. –

Répondre

6

Pas tout à fait une réponse, mais je vais partager mon expérience.

Le reniflage de paramètres a pris quelques années de SQL Server à venir et me mordre, quand je suis retourné à Developer DBA après s'être déplacé vers le travail de DBA principalement prod. J'ai mieux compris le moteur, le fonctionnement de SQL, ce qu'il valait mieux laisser au client, etc. et j'étais un meilleur codeur SQL. Par exemple, SQL dynamique ou CURSOR ou tout simplement mauvais code SQL ne souffrira probablement jamais de reniflage de paramètre. Mais une meilleure programmation ou comment éviter SQL dynamique ou SQL plus élégant sera plus probable. Je l'ai remarqué pour le code de recherche complexe (beaucoup de conditions) et les rapports complexes où les paramètres par défaut ont affecté le plan. Quand je vois comment les développeurs moins expérimentés écriraient ce code, alors il ne souffrira pas de reniflage de paramètre.

Dans tous les cas, je préfère masquer les paramètres avec WITH RECOMPILE. La mise à jour des statistiques ou des index force de toute façon une recompilation. Mais pourquoi recompiler tout le temps? J'ai répondu ailleurs à l'une de vos questions avec un lien qui mentionne que les paramètres sont reniflés lors de la compilation, donc je n'y crois pas non plus.

Le masquage des paramètres est un surdébit, oui, mais il permet à l'optimiseur d'évaluer la requête au cas par cas, plutôt que de recompiler le recouvrement. Surtout avec la recompilation de niveau d'instruction de SQL Server 2005

OPTIMISER POUR INCONNU dans SQL Server 2008 semble également faire exactement la même chose que le masquage. Mon collègue MVP SQL Server et moi-même avons passé un certain temps à enquêter et nous sommes arrivés à cette conclusion.

4

Je suppose que votre problème est dû à des statistiques hors données. Comme vous n'avez pas d'accès DBA au serveur, je vous encourage à demander au DBA quand les statistiques de la dernière fois ont été mises à jour. Cela peut avoir un impact énorme sur les performances. Il semble également que vos tables ne sont pas très bien indexées. Fondamentalement, cela ne «sent» pas comme un problème de reniflage de paramètres, mais plutôt comme un problème de base de données «sain».

Cet article décrit comment vous pouvez obtenir les statistiques la dernière fois ont été mis à jour: Statistics Update Time

+0

Les tables sont bien indexées, mais il est possible que les statistiques ne soient pas mises à jour. Merci pour le rappel. –

+0

Les statistiques sont mises à jour lors de la reconstruction des index. –

2

Je seconde le commentaire au sujet de la vérification des statistiques - je l'ai vu plusieurs cas où la performance d'une requête a chuté spécifiquement une falaise parce que la les statistiques sont périmées. Plus précisément, si vous avez une date dans votre PK, SQL Server pense qu'il y a seulement 10 ou 100 enregistrements qui après une date précise alors qu'il y en a des milliers, il peut choisir des plans de requête terriblement inefficaces parce qu'il pense que l'ensemble de données est beaucoup plus petit qu'il ne l'est réellement.

HTH,

  • Andrew
+0

Il s'avère que les statistiques étaient le problème, mais ils semblaient être à jour. J'ai lancé UPDATE STATISTICS avec FULLSCAN et c'est beaucoup mieux. Je vais mettre dans une requête de surveillance pour m'assurer que je mets à jour les statistiques si elles sont trop obsolètes même si les DBA ont des statistiques automatiques désactivées. –

1

J'ai eu un problème de production exactement comme ça. Un onglet dans l'application qui appelait un proc stocké ne s'afficherait pas. J'ai couru une trace pour le proc spécifique et j'ai vu l'appel. L'application expire en 30 secondes et le proc prendrait près de 40 à 50 secondes pour terminer (a exécuté le proc exactement comme appelé de la trace).

L'étape suivante consistait à déterminer quelle instruction provoquait les balayages que j'ai remarqués dans l'exécution de la procédure. Donc j'ai scripté le proc, enlevé la syntaxe de la procédure et les variables déclarées et couru dans l'analyseur de requête. Il RAN en 3 secondes !!! J'écris ceci pour permettre à n'importe qui là-bas à la recherche de réponses de savoir que cela peut arriver en SQL. Cela provient du problème de reniflage des paramètres. J'ai été en mesure d'identifier ce sujet parce que j'ai identifié la cause comme un plan de requête en cache défectueux! J'ai lu des articles où ils ont dit que cela arrivait à un utilisateur/valeur spécifique. Mais cela peut arriver à n'importe quelle valeur et une fois que cela commence, cela peut être une chose continue.

La solution pour moi était de scripter le proc et l'exécuter à nouveau. Ouais. c'est simple. Un alter fonctionne bien. Pas besoin de laisser tomber et recréer. Cela provoque SQL pour actualiser le plan mis en cache et les choses allaient bien. Je n'ai pas compris comment désactiver cela au niveau du serveur. C'est trop lourd pour nettoyer tous les procs. J'espère que cela aide

+0

Ajoutez WITH RECOMPILE à la fin de votre procédure pour forcer SQLServer à générer un nouveau plan d'exécution pour chaque exécution. – Einstein

+0

Le résultat final a été que la requête a dû être réécrite pour utiliser une construction légèrement différente. –

Questions connexes