Mesure de la complexité des énoncés SQL
la complexité des méthodes dans la plupart des langages de programmation peut être mesurée dans la complexité cyclomatique avec des analyseurs de code source statiques. Est-il similaire métrique pour mesurer la complexité d'une requête SQL?
il est assez simple de mesurer le temps qu'il prend une requête pour revenir, mais que faire si je veux juste être en mesure de quantifier la complexité d'une requête est?
[Edit / Note] Bien que l'obtention du plan d'exécution est utile, ce n'est pas nécessairement ce que j'essaie d'identifier dans cette affaire. Je ne cherche pas la difficulté pour le serveur d'exécuter la requête, je cherche une métrique qui identifie la difficulté pour le développeur d'écrire la requête, et la probabilité qu'elle contienne un défaut.
[Modifier/Note 2] Certes, il y a des moments où la mesure de la complexité n'est pas utile, mais il y a aussi des moments où elle l'est. Pour une discussion plus approfondie sur ce sujet, voir cette question .
9 réponses
les mesures courantes de la complexité logicielle comprennent la complexité cyclomatique (une mesure de la complexité du flux de contrôle) et la complexité de Halstead (une mesure de la complexité de l'arithmétique).
le "flux de contrôle" dans une requête SQL est le mieux relié aux opérateurs "et" et " ou " dans la requête.
la "complexité du calcul" est mieux reliée aux opérateurs tels que les additions ou les jointures implicites.
une fois que vous avez décidé comment catégoriser chaque unité de syntaxe d'une requête SQL pour savoir si elle est" flux de contrôle "ou" calcul", vous pouvez directement calculer des mesures Cyclomatiques ou Halstead.
ce que L'optimiseur SQL fait aux requêtes I penser est absolument hors de propos. Le but de la complexité des mesures est de caractériser comment est dur pour une personne de comprendre la requête, pas comment efficace elle peut être évaluée.
de même, ce que dit la DDL ou si des points de vue sont en cause ou non ne devrait pas être inclus dans de telles mesures de complexité. L'hypothèse derrière ces mesures est que la complexité de la machine à l'intérieur d'une abstraction-usée n'est pas intéressante quand vous l'invoquez simplement, parce que probablement que l'abstraction fait quelque chose de bien compris par le codeur. C'est pourquoi les mesures de Halstead et de Cyclomatic n'incluent pas les sous-programmes appelés dans leur comptage, et je pense que vous pouvez faire une bonne cas où les vues et les informations DDL sont celles "invoquées" abstracttractions.
enfin, combien parfaitement juste ou à quel point parfaitement faux ces nombres de complexité sont n'importe pas beaucoup, tant qu'ils reflètent une certaine vérité sur la complexité et vous pouvez les comparer les uns par rapport aux autres. De cette façon, vous pouvez choisir quels fragments SQL sont les plus complexes, ainsi les trier tous, et concentrer votre attention de test sur les plus compliqués.
Je ne suis pas sûr que la récupération des plans de requête répondra à la question: les plans de requête cachent une partie de la complexité du calcul effectué sur les données avant qu'elles ne soient retournées (ou utilisées dans un filtre); les plans de requête exigent une base de données significative pour être pertinent. En fait, la complexité et la durée de l'exécution sont quelque peu opposées; quelque chose comme "Bon, Rapide, Bon Marché - choisir n'importe lequel de deux".
en fin de compte, il est question des chances de faire une erreur, ou pas comprendre le code que j'ai écrit?
quelque chose comme:
- nombre de tables fois (1
- +1 par expression de jointure (+1 par jointure externe?)
- +1 par prédicat après
WHERE
ouHAVING
- +1 pour
GROUP BY
expression - +1 par
UNION
ouINTERSECT
- +1 par appel de fonction
- +1 pour
CASE
expression - )
s'il vous Plaît n'hésitez pas à tester mon script qui donne un aperçu de la procédure stockée taille, le nombre de dépendances d'objet et le nombre de paramètres -
les requêtes SQL sont déclaratives plutôt que procédurales: elles ne précisent pas comment accomplir leur but. Le moteur SQL créera un plan d'attaque procédural, et ce pourrait être un bon endroit pour chercher la complexité. Essayez d'examiner la sortie de la déclaration expliquer (ou expliquer PLAN), ce sera une description rudimentaire des étapes que le moteur utilisera pour exécuter votre requête.
Eh bien, je ne connais aucun outil qui a fait une telle chose, mais il me semble que ce qui ferait une requête plus compliquée serait mesurée par: le nombre de jointures le nombre de cas où les conditions le nombre de fonctions le nombre de sous-requêtes le nombre de moulages pour différents types de données le nombre de cas relevés le nombre de boucles ou des curseurs le nombre d'étapes d'une transaction
Toutefois, s'il est vrai que le plus comlex requêtes peuvent sembler être le ceux avec les défauts les plus possibles, je trouve que les simples sont très susceptibles de contenir des défauts car ils sont plus susceptibles d'être écrits par quelqu'un qui ne comprend pas le modèle de données et donc ils peuvent sembler fonctionner correctement, mais en fait retourner les mauvaises données. Donc je ne suis pas sûr qu'une telle métrique vous dise grand chose.
Eh bien, si vous utilisez SQL Server, je dirais que vous devriez examiner le coût de la requête dans le plan d'exécution (en particulier le coût de sous-arborescence).
Ici est un lien qui va au-dessus de certaines choses que vous devriez regarder dans le plan d'exécution.
selon votre SGBDR, il peut y avoir des outils de plan de requête qui peuvent vous aider à analyser les étapes que les SGBDR prendront pour récupérer votre requête.
SQL Server Management Studio Express a un plan d'exécution des requêtes intégré. Pervasive PSQL a son plan D'interrogation Finder. DB2 a des outils similaires (oublié comment ils s'appellent).
bonne question. Le problème est que pour une requête SQL comme:
SELECT * FROM foo;
la complexité peut dépendre de ce qu'est" foo " et de l'implémentation de la base de données. Pour une fonction comme:
int f( int n ) {
if ( n == 42 ) {
return 0;
}
else {
return n;
}
}
il n'y a pas de telle dépendance.
cependant, je pense qu'il devrait être possible de trouver des mesures utiles pour un SELECT, même si elles ne sont pas très exactes, et je serai intéressé de voir quelles réponses cela obtient.
en l'absence de tout outil permettant de le faire, une approche pragmatique consisterait à s'assurer que les requêtes analysées sont formatées de manière cohérente et à compter ensuite les lignes de code.
utilisez alternativement la taille des requêtes en octets lorsqu'elles sont enregistrées dans le fichier (en veillant à ce que toutes les requêtes soient enregistrées en utilisant le même codage de caractères).
pas brillant, mais une approximation raisonnable de la complexité en l'absence de tout autre je pense.