Procédure stockée SQL Server – 'IF statement' vs 'Where criteria'

La question d'un assez long moment bouillonnait dans ma tête, celle des deux procédures stockées suivantes que l'on ferait mieux.

Proc 1

CREATE PROCEDURE GetEmployeeDetails @EmployeeId uniqueidentifier, @IncludeDepartmentInfo bit AS BEGIN SELECT * FROM Employees WHERE Employees.EmployeeId = @EmployeeId IF (@IncludeDepartmentInfo = 1) BEGIN SELECT Departments.* FROM Departments, Employees WHERE Departments.DepartmentId = Employees.DepartmentId AND Employees.EmployeeId = @EmployeeId END END 

Proc 2

 CREATE PROCEDURE GetEmployeeDetails @EmployeeId uniqueidentifier, @IncludeDepartmentInfo bit AS BEGIN SELECT * FROM Employees WHERE Employees.EmployeeId = @EmployeeId SELECT Departments.* FROM Departments, Employees WHERE Departments.DepartmentId = Employees.DepartmentId AND Employees.EmployeeId = @EmployeeId AND @IncludeDepartmentInfo = 1 END 

la seule différence entre les deux est l'utilisation de «if statment».

si proc 1 / proc 2 est appelé avec des valeurs alternées de @IncludeDepartmentInfo, alors, selon moi, proc 2 fonctionnera mieux, car il conservera le même plan de requête quelle que soit la valeur de @IncludeDepartmentInfo, alors que proc1 changera le plan de requête dans chaque appel

les réponses sont vraiment apéritives

PS: c'est juste un scénario, s'il vous plaît ne pas aller aux résultats de la requête explicite, mais l'essence de l'exemple. Je suis vraiment particulier sur le résultat de l'optimiseur de requête (dans les deux cas de 'si et où' et leur différence), il y a beaucoup d'aspects qui, je le sais, pourraient affecter les performances que je veux éviter dans cette question.

 SELECT Departments.* FROM Departments, Employees WHERE Departments.DepartmentId = Employees.DepartmentId AND Employees.EmployeeId = @EmployeeId AND @IncludeDepartmentInfo = 1 

Lorsque SQL comstack une requête comme celle-ci, elle doit être compilée pour toute valeur de @IncludeDepartmentInfo. Le plan résultant peut bien être celui qui parsing les tables et effectue la jointure, puis vérifie la variable, ce qui entraîne des E / S inutiles. L'optimiseur peut être intelligent et déplacer la vérification de la variable avant les opérations d'E / S réelles dans le plan d'exécution, mais cela n'est jamais garanti. C'est pourquoi je recommand toujours d'utiliser des IF explicites dans le T-SQL pour les requêtes qui doivent être exécutées très différemment en fonction d'une valeur de variable (l'exemple typique étant des conditions OU).

L'observation de gbn est également importante: du sharepoint vue de la design de l'API, il est préférable d'avoir un type de return cohérent (c'est-à-dire de toujours returnner la même forme et le même nombre d'sets de résultats).

Du sharepoint vue de la cohérence, le numéro 2 renvoie toujours deux jeux de données. En cas de surcharge, vous ne disposez pas d'une méthode de code client susceptible de renvoyer un résultat, peut-être pas.

Si vous réutilisez ce code, l'autre client appelant devra également connaître ce drapeau.

Si le code fait 2 choses différentes, alors pourquoi pas 2 procs stockés différents?

Enfin, il est de loin préférable d'utiliser une syntaxe JOIN moderne et une jonction séparée du filtrage. Dans ce cas, personnellement , j'utiliserais EXISTS aussi.

 SELECT D.* FROM Departments D JOIN Employees E ON D.DepartmentId = E.DepartmentId WHERE E.EmployeeId = @EmployeeId AND @IncludeDepartmentInfo = 1 

Lorsque vous utilisez l'instruction 'if', vous pouvez exécuter une seule requête au lieu de deux. Je pense qu'une requête serait presque toujours plus rapide que deux. Votre point sur les plans de requête peut être valide si la première requête était complexe et prenait beaucoup de time à s'exécuter, et la seconde était sortingviale. Cependant, la première requête semble récupérer une seule ligne basée sur une key primaire – probablement assez rapide à chaque fois. Donc, je garderais le 'si' – mais je testerais pour vérifier.

La différence de performance serait trop petite pour que quelqu'un puisse le remarquer.

L'optimization prématurée est la racine de tout Mal. Arrêtez de vous soucier des performances et commencez à implémenter des fonctionnalités qui font sourire vos clients.