Les deux derniers mercredis, nous avons organisé une série de webinaires en deux parties traitant des problèmes de sensibilité des paramètres :
- Procédures stockées, paramètres, problèmes…
Kimberly L. Tripp et Aaron Bertrand
24 janvier
Vous avez manqué ? Inscrivez-vous pour le regarder maintenant ! - S'attaquer au reniflage des paramètres à l'aide de SentryOne
Aaron Bertrand, Kimberly L. Tripp et Andy Mallon
31 janvier
Vous l'avez manqué ? Regardez-le maintenant !
Certaines questions ont été posées au cours des deux webinaires, et j'ai pensé les compiler et y répondre ici (certaines des réponses sont venues d'Andy pendant le webinaire).
Dans un problème que nous avons vu récemment, nous constatons que des plans sont très rapidement supprimés du cache. Nous n'effectuons rien de ce que vous décrivez (
DBCC FREEPROCCACHE
etc.); la pression de la mémoire pourrait-elle également provoquer cela ?
Oui, la pression de la mémoire pourrait être un facteur (voir ce post), et je sais qu'il y a des enquêtes sur les problèmes potentiels avec la gestion de la mémoire de SQL Server à cet égard également.
D'un participant :"Pas une question, mais un commentaire à l'utilisateur demandant à propos des nombreuses fois que son cache de plan est vidé. Nous avons eu cela aussi et, en effet, c'était une pression de mémoire. Nous avions mal configuré la mémoire maximale du serveur, c'était corrigé en utilisant la formule mentionnée ici, puis nous avons eu la procédure de cet article exécutée toutes les 10 minutes (nous avons des tonnes de SQL dynamique, utilisé une seule fois)."
Et si vous utilisiez
OR
dans la clause where au lieu deAND
, le problème persisterait-il ?
Typiquement si vous utilisez
OR
dans ce type de modèle, vous obtiendrez toutes les lignes à chaque fois, à moins que chaque paramètre ne soit rempli avec des valeurs qui filtrent les lignes. Cela modifie la sémantique de la requête de "toutes ces choses doivent être vraies" à "n'importe laquelle de ces choses peut être vraie". Néanmoins, le plan compilé pour le premier ensemble de paramètres sera toujours mis en cache et conservé pour les exécutions futures, que vos clauses utilisentAND
ouOR
.
Est-ce
1=1
signaler une bonne approche ? N'est-il pas préférable de n'ajouter que les paramètres fournis et donc d'éviter le vilain1=1
?
Le
1 = 1
est pratiquement ignoré par SQL Server, mais permet à toutes les clauses conditionnelles d'être ajoutées avecAND
pour que vous n'ayez pas à traiter le *premier* différemment. Voici l'alternative :SET @IncludedWhereClauseYet bit = 0; SET @sql = N'SELECT cols FROM dbo.Table'; IF @param1 IS NOT NULL BEGIN IF @IncludedWhereClauseYet = 0 BEGIN SET @sql += N' WHERE '; SET @IncludedWhereClauseYet = 1; END ELSE BEGIN SET @sql += N' AND '; END SET @sql += N' @param1 = @param1'; END IF @param2 IS NOT NULL BEGIN IF @IncludedWhereClauseYet = 0 ... END ...Le
1=1
vous permet de simplifier, en vous permettant de toujours préfixer n'importe quelle clause avecAND
. Le code ci-dessus devient :SET @sql = N'SELECT cols FROM dbo.Table WHERE 1 = 1'; IF @param1 IS NOT NULL BEGIN SET @sql += N' AND @param1 = @param1'; END IF @param2 IS NOT NULL BEGIN SET @sql += N' AND @param2 = @param2'; ENDVous pourriez peut-être utiliser une clause initiale différente pour éviter toutes les conditions, comme
WHERE PrimaryKey > 0
ouWHERE PrimaryKey IS NOT NULL
, puis chaque clause suivante pourrait commencer parAND
. Mais1 = 1
, bien que laid, est inoffensif, et à mon humble avis n'est pas moins laid que d'ajouter une clause *réelle* mais dénuée de sens, sauf qu'une clause *réelle* pourrait affecter le plan.N'oubliez pas que lorsque vous construisez du code T-SQL avec T-SQL, vous devez penser à deux aspects de "laid" - parfois vous dépannerez le code ci-dessus, et parfois vous dépannerez la requête qui sort de ce. Faites attention à ne pas sacrifier l'un au profit de l'autre.
QUELLE?! J'ai totalement raté ça…
WITH RECOMPILE
. Je pensais que ça vidait le plan, mais ça le laisse seul pour cette exécution… c'est très important à savoir !
Assurez-vous simplement que vous êtes également conscient des inconvénients.
Voir cet excellent article de Paul White.
Est-ce que
OPTION OPTIMIZE FOR @parametername UNKNOWN
n'est plus préféré dans les versions SQL plus récentes ?
Je ne pense pas que ce soit meilleur ou pire dans les versions modernes que lors de son introduction dans SQL Server 2008. Autant que je sache, même avec toutes les modifications apportées à l'optimiseur et à l'estimateur de cardinalité, ce bit se comporte toujours de la même manière.
Y a-t-il une charge sur le serveur, si j'active la capture des statistiques de procédure et des statistiques de requête dans SentryOne ?
La collecte des statistiques de procédure et de requête doit être activée par défaut. Toute collecte de données a un coût, mais SQL Sentry fait très attention au coût encouru par la collecte.
La recherche sur RS ne l'utilisait pas comme prédicat résiduel, elle cherchait quelque chose d'autre que je ne pouvais pas voir.
Merci, je vais revoir cet exemple et bloguer sur les démos séparément, en veillant à inclure tous les détails pertinents qui n'étaient pas évidents à partir du schéma de plan seul.
N'est-il pas vrai que l'ajout de certaines des colonnes nécessaires en tant que
INCLUDE
s ne rend-il pas l'index plus efficace car la recherche de clé ne sera pas éliminée ? Je pense que le pourcentage ne devrait pas changer à moins que vous n'éliminiez réellement la recherche de clé.
Strictement, oui, c'est vrai. La requête d'origine était un mauvais exemple primordial, utilisant
SELECT *
et un index manquant un nombre désespéré de colonnes. Le point que j'essayais de faire valoir est que l'onglet Analyse de l'index vous encourage à la fois (a) à améliorer la requête et (b) à faire la couverture de l'index. Le score est là pour vous inciter à faire l'un ou l'autre ou les deux - si vous modifiez la requête de sorte que vous avez besoin de moins de colonnes, l'index se rapproche également de la couverture de la requête. Si vous envisagez de créer un nouvel index de couverture distinct, vous disposez également des informations sur les colonnes requises pour couvrir cette requête spécifique. Techniquement, vous avez raison, ajouter une colonne d'inclusion tout en nécessitant une recherche pour 4 autres ne va pas améliorer les performances de cette requête spécifique et ne va pas améliorer l'index, mais cela indique que vous ' se rapproche. L'espoir est que vous ne vous contentez pas d'ajouter une colonne d'inclusion et d'ignorer le reste. Nous ne savons pas quand vous allez vous arrêter, donc je ne sais pas s'il existe une solution parfaite - nous ne voulons certainement pas décourager utilisateurs de rendre leurs index mieux adaptés à leurs requêtes.
Pourquoi voyons-nous des requêtes utilisant le paramètre de prénom et le paramètre de nom de famille résumés sous une déclaration utilisant uniquement un paramètre de nom de famille ?
MISE À JOUR : C'est intentionnel. Le regroupement sous Afficher les totaux regroupe la même procédure appelée avec toutes les différentes combinaisons de paramètres. Vous pouvez donc l'utiliser d'abord pour déterminer quels paramètres ont tendance à entraîner les pires performances, puis, dans ce cadre, déterminer s'il existe ou non une distorsion des données. Un paramètre qui mène à une recherche sur une colonne non indexée, par exemple, remontera probablement vers le haut de manière assez fiable, et vous pouvez voir cela en combinaison avec d'autres paramètres qui sont passés et également comparés à tous les appels où ce paramètre était ' t passé.
Cela dit, nous chercherons à affiner ce comportement de regroupement au fur et à mesure que nous terminerons les modifications actuellement en cours pour l'écran Top SQL.
Existe-t-il une documentation sur l'utilisation d'un guide de plan ? Je n'aurais actuellement aucune idée de comment faire cela.
C'est quelque chose d'autre sur lequel je voulais bloguer, mais Microsoft a quelques sujets ici en attendant (et consultez tous les liens connexes dans la barre latérale).
Dois-je activer quelque chose pour obtenir le graphique de l'historique des requêtes ?
Non, cela devrait être activé sur toutes les versions modernes de l'application client SentryOne. Si vous ne le voyez pas, essayez
Tools > Reset Layout
; si cela ne fonctionne pas, contactez [email protected].
Existe-t-il des cas où forcer le dernier bon plan connu à l'aide du magasin de requêtes lorsqu'une régression de plan s'avère être une mauvaise idée ? Cela aura-t-il tendance à masquer des problèmes qu'il est préférable de résoudre en modifiant l'énoncé comme vous l'avez montré ?
Forcer un plan est souvent une option de dernier recours, et j'ai tendance à la réserver aux cas où vous ne pouvez vraiment, vraiment, vraiment pas corriger l'instruction (ou modifier l'index). Forcer un plan peut toujours conduire à un mauvais comportement, car c'est toujours un humain qui fait ce choix, et vous pourriez le faire sur la base de mauvaises informations. La régression peut être due à un changement de plan, mais si vous jugez qu'il s'agit d'une régression parce que la durée d'exécution était plus longue, avez-vous recherché d'autres raisons possibles ? Par exemple, disons que le système a été redémarré ou qu'il y a eu un basculement, et a obtenu un nouveau plan parce que l'ancien a été expulsé, et peut-être que les statistiques ont également changé entre-temps, mais maintenant la requête s'exécute plus longtemps non pas parce que le plan est pire mais plutôt parce que les tampons étaient vides. Alors oui, je ne suggérerais certainement pas d'imposer un plan à chaque régression.
SentryOne ne capture pas toujours des données ou des paramètres tout le temps, donc je n'ai pas assez d'informations. Comment puis-je m'assurer que SentryOne capture les paramètres et les plans d'exécution à tout moment ?
Vous ne pouvez vraiment pas, car tout dépend de la façon dont vos requêtes sont exécutées, de la façon dont nous les capturons et de la rapidité avec laquelle elles s'exécutent. Souvent, vos requêtes ne s'exécutent pas assez longtemps pour être entièrement capturées, et nous devons nous fier aux vues de statistiques de requête/procédure agrégées de SQL Server, qui ne collectent pas d'informations sur les paramètres. Vous pouvez modifier les paramètres de collecte de Top SQL Source pour en capturer davantage et à un intervalle plus fréquent, mais vous devez équilibrer la quantité de données que vous collectez avec la quantité d'informations supplémentaires qu'elle vous achète.
Puis-je interroger les informations afin de pouvoir automatiser et générer des rapports ?
Nous n'avons rien de prêt à faire pour vous, mais permettez-moi de le rapporter à l'équipe et de voir quel type d'options nous pouvons proposer. Une chose avec laquelle j'ai joué pour ce webinaire était de créer une condition consultative pour détecter les types de régressions que nous recherchons, mais le temps est devenu un facteur.
Comment décidons-nous quand utiliser
OPTION (RECOMPILE)
, comme chaque jour nous recevons différents plans pour différents paramètres ?
Je dirais de commencer par les requêtes qui fluctuent le plus avec la sensibilité des paramètres. Si j'ai une requête qui prend parfois 2 secondes, mais parfois 30 secondes, et une autre qui dure entre 4 secondes et 6 secondes,
je vais me concentrer sur la première.
Lequel est préférable d'utiliser,
OPTION (RECOMPILE)
ouQUERYTRACEON
, dans le cas du reniflage de paramètres.
Je préfère
OPTION (RECOMPILE)
pour deux raisons. Premièrement, il s'auto-documente; personne ne lisant le code ne se demandera ce qu'il fait, mais tous ceux qui liront le code n'auront pas mémorisé les numéros TF comme 4136. Deuxièmement, cela ne nécessite pas d'autorisations élevées - essayez d'utiliserQUERYTRACEON
comme un péon.
Est-il possible d'alerter ou de signaler des procédures qui prennent plus de temps que d'habitude ? Le plus intéressé par les procédures à nombre élevé.
Absolument, vous pouvez utiliser une condition consultative, mais cela peut devenir un peu compliqué car - pour les procédures qui s'exécutent même parfois en dessous du seuil de collecte - vous devrez comparer des instantanés des statistiques de procédure DMV. J'ai également ajouté un rappel sur le blog à propos de celui-ci, car c'est quelque chose que j'ai aidé les clients à mettre en œuvre dans le passé.
Microsoft fait du réglage automatique la valeur par défaut pour Azure SQL Database, y compris la correction automatique des plans. Cela vous semble-t-il une bonne idée ?
Je réserverai mon jugement jusqu'à ce que moi (ou certains clients) ayons joué avec. Décider comment s'accorder est déjà assez difficile pour les mortels; les mortels qui écrivent un logiciel à régler pour vous semblent au moins aussi difficiles, sinon plus. Quand Andy a vu cette question, il m'a dit que cela lui rappelait SQL Server 2000 - le discours marketing était alors qu'il était tellement auto-ajustable que nous n'aurions plus besoin de DBA. Cette affirmation n'a pas bien vieilli.
Pouvoir sélectionner les deux points sur le graphique de l'historique des requêtes et les comparer serait bien.
Je suis d'accord.
Restez à l'écoute.