Lorsque vous avez une requête ou une procédure stockée qui nécessite un réglage des performances, quelles sont les premières choses que vous essayez?
sql
sql-server
database
performance
Terrapin
la source
la source
Réponses:
Voici la liste pratique des choses que je donne toujours à quelqu'un qui me pose des questions sur l'optimisation.
Nous utilisons principalement Sybase, mais la plupart des conseils s'appliqueront à tous les niveaux.
SQL Server, par exemple, est livré avec une multitude de bits de surveillance / réglage des performances, mais si vous n'avez rien de tel (et peut-être même si vous le faites), je considérerais ce qui suit ...
99% des problèmes que j'ai vus sont causés par le fait de placer trop de tables dans une jointure . Le correctif pour cela est de faire la moitié de la jointure (avec certaines des tables) et de mettre en cache les résultats dans une table temporaire. Ensuite, effectuez le reste de la requête en joignant cette table temporaire.
Liste de contrôle de l'optimisation des requêtes
#temp
les tables peuvent être bien meilleures que les@table
variables avec de gros volumes (des milliers de lignes).la source
la source
Un peu hors sujet mais si vous avez le contrôle sur ces problèmes ...
Haut niveau et fort impact.
la source
CREATE INDEX
Assurez-vous qu'il existe des index disponibles pour vos clauses
WHERE
etJOIN
. Cela accélérera considérablement l'accès aux données.Si votre environnement est un data mart ou un entrepôt, les index devraient abonder pour presque toutes les requêtes imaginables.
Dans un environnement transactionnel , le nombre d'index doit être inférieur et leurs définitions plus stratégiques afin que la maintenance des index ne diminue pas les ressources. (La maintenance d'index se produit lorsque les feuilles d'un index doivent être modifiées pour refléter une modification de la table sous-jacente, comme avec les opérations
INSERT, UPDATE,
etDELETE
.)Soyez également attentif à l'ordre des champs dans l'index - plus un champ est sélectif (cardinalité élevée), plus il doit apparaître tôt dans l'index. Par exemple, disons que vous recherchez des voitures d'occasion:
Le prix a généralement une cardinalité plus élevée. Il se peut qu'il n'y ait que quelques dizaines de couleurs disponibles, mais très probablement des milliers de prix différents.
Parmi ces choix d'index,
idx01
fournit le chemin le plus rapide pour satisfaire la requête:En effet, moins de voitures satisferont le prix que le choix de couleur, ce qui donne au moteur de requête beaucoup moins de données à analyser.
Je suis connu pour avoir deux index très similaires ne différant que dans l'ordre des champs pour accélérer les requêtes (prénom, nom) dans l'un et (nom, prénom) dans l'autre.
la source
Une astuce que j'ai récemment apprise est que SQL Server peut mettre à jour des variables locales ainsi que des champs, dans une instruction de mise à jour.
Ou la version la plus lisible:
Je l'ai utilisé pour remplacer les curseurs / jointures compliqués lors de la mise en œuvre de calculs récursifs, et j'ai également beaucoup gagné en performances.
Voici des détails et des exemples de code qui ont apporté des améliorations fantastiques aux performances: http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---the-optimal. aspx
la source
En supposant MySQL ici, utilisez EXPLAIN pour découvrir ce qui se passe avec la requête, assurez-vous que les index sont utilisés aussi efficacement que possible et essayez d'éliminer les types de fichiers. MySQL hautes performances: optimisation, sauvegardes, réplication, etc. est un excellent livre sur ce sujet, tout comme MySQL Performance Blog .
la source
@Terrapin, il y a quelques autres différences entre isnull et coalesce qui méritent d'être mentionnées (en plus de la conformité ANSI, ce qui est important pour moi).
Coalesce contre IsNull
la source
Parfois, dans SQL Server, si vous utilisez un OR dans une clause where, il sera vraiment très performant. Au lieu d'utiliser le OU, faites simplement deux sélections et unissez-les ensemble. Vous obtenez les mêmes résultats à 1000 fois la vitesse.
la source
Regardez la clause where - vérifiez l'utilisation des index / vérifiez que rien de stupide n'est fait
la source
Je vais généralement commencer par les jointures - je vais supprimer chacune d'elles de la requête une par une et réexécuter la requête pour avoir une idée s'il y a une jointure particulière avec laquelle j'ai un problème.
la source
Sur toutes mes tables temporaires, j'aime ajouter des contraintes uniques (le cas échéant) pour créer des index et des clés primaires (presque toujours).
la source
J'ai pris l'habitude de toujours utiliser des variables de liaison. Il est possible que les variables de liaison n'aident pas si le SGBDR ne met pas en cache les instructions SQL. Mais si vous n'utilisez pas de variables de liaison, le SGBDR n'a pas la possibilité de réutiliser les plans d'exécution de requête et les instructions SQL analysées. Les économies peuvent être énormes: http://www.akadia.com/services/ora_bind_variables.html . Je travaille principalement avec Oracle, mais Microsoft SQL Server fonctionne à peu près de la même manière.
D'après mon expérience, si vous ne savez pas si vous utilisez ou non des variables de liaison, vous ne l'êtes probablement pas. Si la langue de votre application ne les prend pas en charge, trouvez-en une qui le fait. Parfois, vous pouvez corriger la requête A en utilisant des variables de liaison pour la requête B.
Après cela, je parle à notre DBA pour savoir ce qui cause le plus de douleur au SGBDR. Notez que vous ne devriez pas demander "Pourquoi cette requête est-elle lente?" C'est comme demander à votre médecin de vous retirer l'appendice. Bien sûr, votre requête peut être le problème, mais il est tout aussi probable que quelque chose ne va pas. En tant que développeurs, nous avons tendance à penser en termes de lignes de code. Si une ligne est lente, corrigez cette ligne. Mais un SGBDR est un système vraiment compliqué et votre lenteur de requête peut être le symptôme d'un problème beaucoup plus important.
Beaucoup trop de conseils de réglage SQL sont des idoles de culte du fret. La plupart du temps, le problème n'est pas lié ou peu lié à la syntaxe que vous utilisez, il est donc normalement préférable d'utiliser la syntaxe la plus propre possible. Ensuite, vous pouvez commencer à chercher des moyens de régler la base de données (pas la requête). Ne modifiez la syntaxe que lorsque cela échoue.
Comme pour tout réglage des performances, collectez toujours des statistiques significatives. N'utilisez pas l'heure de l'horloge murale à moins que ce ne soit l'expérience utilisateur que vous réglez. Au lieu de cela, regardez des choses comme le temps CPU, les lignes récupérées et les blocs lus sur le disque. Trop souvent, les gens optimisent pour la mauvaise chose.
la source
Première étape: regardez le plan d'exécution des requêtes!
TableScan -> bad
NestedLoop -> meh warning
TableScan derrière un NestedLoop -> DOOM!
SET STATISTICS IO ON
SET STATISTICS TIME ON
la source
Exécuter la requête en utilisant WITH (NoLock) est à ma place une opération presque standard. Quiconque est surpris en train d'exécuter des requêtes sur les tables de dizaines de gigaoctets sans qu'il soit retiré et abattu.
la source
Convertissez les requêtes NOT IN en GAUCHE OUTER JOINS si possible. Par exemple, si vous souhaitez rechercher toutes les lignes de Table1 qui ne sont pas utilisées par une clé étrangère dans Table2, vous pouvez le faire:
Mais vous obtenez de bien meilleures performances avec ceci:
la source
@ DavidM
Dans SQL Server, le plan d'exécution vous donne la même chose - il vous indique quels index sont touchés, etc.
la source
Indexez la (les) table (s) en fonction des clm sur lesquelles vous filtrez
la source
Pas nécessairement une astuce de performance SQL en soi, mais certainement liée:
Une bonne idée serait d'utiliser memcached dans la mesure du possible car il serait beaucoup plus rapide de simplement récupérer les données précompilées directement depuis la mémoire plutôt que de les récupérer depuis la base de données. Il y a aussi une saveur de MySQL qui a été intégrée à Memcached (tiers).
la source
Assurez-vous que vos longueurs d'index sont aussi petites que possible. Cela permet à la base de données de lire plus de clés à la fois à partir du système de fichiers, accélérant ainsi vos jointures. Je suppose que cela fonctionne avec toutes les bases de données, mais je sais que c'est une recommandation spécifique pour MySQL.
la source
Je recherche:
la source
Habituellement, la première ligne de mes procédures stockées, sauf si j'ai réellement besoin d'utiliser
@@ROWCOUNT
.la source
Dans SQL Server, utilisez la directive nolock. Il permet à la commande select de se terminer sans avoir à attendre - généralement d'autres transactions pour se terminer.
la source
Supprimez les curseurs là où ils ne sont pas nécessaires.
la source
Supprimez les appels de fonction dans Sprocs où beaucoup de lignes appelleront la fonction.
Mon collègue a utilisé des appels de fonction (obtenir lastlogindate à partir de userid comme exemple) pour renvoyer des jeux d'enregistrements très larges.
Chargé de l'optimisation, j'ai remplacé les appels de fonction dans le sproc par le code de la fonction: j'ai eu beaucoup de temps d'exécution de sprocs de> 20 secondes à <1.
la source
la source
J'aime utiliser
Plus de
Quand je n'ai pas besoin du support d'arguments multiples que vous offre coalesce.
http://blog.falafel.com/2006/04/05/SQLServerArcanaISNULLVsCOALESCE.aspx
la source
Ne préfixez pas les noms de procédure stockée par "sp_" car les procédures système commencent toutes par "sp_" et SQL Server devra rechercher plus dur pour trouver votre procédure lorsqu'elle sera appelée.
la source
Sale lit -
Empêche les verrous morts là où l'intégrité transactionnelle n'est pas absolument nécessaire (ce qui est généralement vrai)
la source
Je vais toujours d'abord à SQL Profiler (s'il s'agit d'une procédure stockée avec beaucoup de niveaux d'imbrication) ou au planificateur d'exécution de requêtes (s'il s'agit de quelques instructions SQL sans imbrication). 90% du temps, vous pouvez trouver le problème immédiatement avec l'un de ces deux outils.
la source