Question

j'avais l'habitude d'écrire des déclarations SQL comme

select * from teacher where (TeacherID = @TeacherID) OR (@TeacherID = -1)

En savoir plus

et transmettez la valeur @TeacherID = -1 pour sélectionner tous les enseignants

Maintenant, je m'inquiète de la performance que vous pouvez me dire est une bonne pratique ou une mauvaise?

merci beaucoup

Était-ce utile?

La solution

Si TeacherID est indexé et vous transmettez une valeur autre que -1 comme TeacherID pour rechercher les détails d'un enseignant spécifique, cette requête finira par effectuer une analyse complète de la table plutôt que l'option potentiellement beaucoup plus efficace consistant à rechercher dans l'index pour récupérer les détails de l'enseignant spécifique...

...Sauf si vous utilisez SQL 2008 SP1 CU5 et versions ultérieures et que vous utilisez le OPTION (RECOMPILE) indice.Voir Conditions de recherche dynamiques dans T-SQL pour l'article définitif sur le sujet.

Autres conseils

Nous l'utilisons de manière très limitée dans les procédures stockées.

Le problème est que le moteur de base de données n'est pas capable de conserver un bon plan de requête.Lorsque vous traitez un grand nombre de données, cela peut avoir un impact négatif important sur les performances.

Cependant, pour les ensembles de données plus petits (je dirais moins de 1 000 enregistrements, mais c'est une supposition), cela devrait aller.Vous devrez tester dans votre environnement particulier.

S'il s'agit d'une procédure stockée, vous souhaiterez peut-être inclure quelque chose comme un WITH RECOMPILE option afin que le le plan est régénéré à chaque exécution.Cela augmente (légèrement) le temps de chaque exécution, mais sur plusieurs exécutions, cela peut en fait réduire le temps d'exécution moyen.En outre, cela permet à la base de données d'inspecter la requête réelle et "court-circuit" les pièces qui ne sont pas nécessaires à chaque appel.

Si vous créez directement votre SQL et le transmettez, je vous suggère de rendre la partie qui construit votre SQL un peu plus intelligente afin qu'elle n'inclue que la partie de la clause Where dont vous avez réellement besoin.


Une autre voie que vous pourriez envisager consiste à utiliser les requêtes UNION ALL par opposition aux paramètres facultatifs.Par exemple:

SELECT * FROM Teacher WHERE (TeacherId = @TeacherID)
UNION ALL
SELECT * FROM Teacher WHERE (@TeacherId = -1)

Cela accomplit en fait exactement la même chose ;cependant, le plan de requête peut être mis en cache.Nous avons également utilisé cette méthode à quelques endroits et avons constaté des améliorations de performances par rapport à l'utilisation de WITH RECOMPILE.Nous ne faisons pas cela partout car certaines de nos requêtes sont extrêmement compliquées et je préfère avoir une baisse de performances plutôt que de les compliquer davantage.

En fin de compte, vous devrez faire de nombreux tests.


Il y a ici une deuxième partie que vous devriez reconsidérer. SELECT *. Il est TOUJOURS préférable de nommer réellement les colonnes que vous souhaitez renvoyer et pour m'assurer que vous êtes seulement en renvoyant ceux dont vous aurez réellement besoin.Le déplacement de données au-delà des limites du réseau coûte très cher et vous pouvez généralement obtenir une amélioration considérable des performances simplement en spécifiant exactement ce que vous souhaitez.De plus si ce dont vous avez besoin est très limité vous pouvez parfois le faire couvrant les index afin que le moteur de base de données n'ait même pas besoin de toucher aux tables sous-jacentes pour obtenir les données souhaitées.

Si vous êtes vraiment inquiet pour la performance, vous pouvez rompre votre procédure pour appeler deux Procs différents: un pour tous les enregistrements et une fois sur le paramètre.

If @TeacherID = -1
   exec proc_Get_All_Teachers
else
   exec proc_Get_Teacher_By_TeacherID @TeacherID

Chacun peut être optimisé individuellement.

C'est votre système, comparez les performances.Envisagez d'optimiser sur le choix le plus populaire.Si la plupart des utilisateurs vont sélectionner un seul enregistrement, pourquoi s'adapter à leur préformation pour accueillir les quelques-uns qui selct Tous les enseignants (et doivent avoir une attente raisonnable de la performance.).

Je sais qu'une seule requête SELECT est plus facile à maintenir, mais à un moment donné, la facilité d'entretien cède finalement la place à la performance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top