Comment ignorer ou éliminer la dernière jointure à gauche dans la requête

J'ai la procédure stockée paramétrée facultative, mais la requête fonctionne bien et a l'indexing appropriée sur la table. Mais lorsque le dernier paramètre est passé, le code de département i: e et les autres peuvent être aussi NULL. La requête prend longtime et ne produit pas le résultat. Le time continue d'augmenter mais le résultat n'est jamais récupéré.

Toutes les suggestions sur comment ignorer la jointure inutilisée qui n'est pas liée dans ce scénario.

Dans ce scénario, je peux ignorer la jointure ci-dessous.

LEFT JOIN EMPLOYEEADDRESS EA ON EA.EmployeeDetailsFK = ED.Id 

Toutes les suggestions comment puis-je éviter cette jointure pour accélérer l'exécution de la requête.

Veuillez find la requête complète ci-dessous

 CREATE PROCEDURE prGetStudentData ( @FirstName VARCHAR(50) = NULL, @EmployeeCode VARCHAR(50) = NULL, @Address VARCHAR(50) = NULL, @DepartmentCode VARCHAR(50) = NULL ) AS BEGIN SELECT E.* FROM EMPLOYEE E INNER JOIN EMPLOYEEDETAILS ED ON ED.EmployeeFK = E.Id LEFT JOIN EMPLOYEEADDRESS EA ON EA.EmployeeDetailsFK = ED.Id LEFT JOIN DEPARTMENT D ON D.Id = ED.DepartmentFK WHERE (@FirstName IS NULL OR (E.FirstName = @FirstName) AND (@EmployeeCode IS NULL OR (ED.EmployeeCode = @EmployeeCode) AND (@Address IS NULL OR (EA.Address = @Address) AND (@DepartmentCode IS NULL OR (D.DepartmentCode = @DepartmentCode) END 

Essaye ça:

 SELECT E.* FROM EMPLOYEE E INNER JOIN EMPLOYEEDETAILS ED ON ED.EmployeeFK = E.Id LEFT JOIN EMPLOYEEADDRESS EA ON EA.EmployeeDetailsFK = ED.Id LEFT JOIN DEPARTMENT D ON @DepartmentCode IS NOT NULL AND D.Id = ED.DepartmentFK WHERE (@FirstName IS NULL OR (E.FirstName = @FirstName)) AND (@EmployeeCode IS NULL OR (ED.EmployeeCode = @EmployeeCode)) AND (@Address IS NULL OR (EA.Address = @Address)) AND (@DepartmentCode IS NULL OR (D.DepartmentCode = @DepartmentCode)) 

ou

 SELECT E.* FROM EMPLOYEE E INNER JOIN EMPLOYEEDETAILS ED ON ED.EmployeeFK = E.Id LEFT JOIN EMPLOYEEADDRESS EA ON EA.EmployeeDetailsFK = ED.Id WHERE (@FirstName IS NULL OR (E.FirstName = @FirstName) AND (@EmployeeCode IS NULL OR (ED.EmployeeCode = @EmployeeCode) AND (@Address IS NULL OR (EA.Address = @Address) AND (@DepartmentCode IS NULL OR EXISTS(SELECT * FROM DEPARTMENT D WHERE D.Id = ED.DepartmentFK AND D.DepartmentCode = @DepartmentCode) ) 

Une réponse facile est de choisir une sélection conditionnelle.

 CREATE PROCEDURE prGetStudentData ( @FirstName VARCHAR(50) = NULL, @EmployeeCode VARCHAR(50) = NULL, @Address VARCHAR(50) = NULL, @DepartmentCode VARCHAR(50) = NULL ) AS BEGIN IF @DepartmentCode IS NULL SELECT E.* FROM EMPLOYEE E INNER JOIN EMPLOYEEDETAILS ED ON ED.EmployeeFK = E.Id LEFT JOIN EMPLOYEEADDRESS EA ON EA.EmployeeDetailsFK = ED.Id LEFT JOIN DEPARTMENT D ON D.Id = ED.DepartmentFK WHERE (@FirstName IS NULL OR (E.FirstName = @FirstName) AND (@EmployeeCode IS NULL OR (ED.EmployeeCode = @EmployeeCode) AND (@Address IS NULL OR (EA.Address = @Address) AND (@DepartmentCode IS NULL OR (D.DepartmentCode = @DepartmentCode) ELSE SELECT E.* FROM EMPLOYEE E INNER JOIN EMPLOYEEDETAILS ED ON ED.EmployeeFK = E.Id LEFT JOIN EMPLOYEEADDRESS EA ON EA.EmployeeDetailsFK = ED.Id WHERE (@FirstName IS NULL OR (E.FirstName = @FirstName) AND (@EmployeeCode IS NULL OR (ED.EmployeeCode = @EmployeeCode) AND (@Address IS NULL OR (EA.Address = @Address) END 

Les process stockés qui ont plusieurs parameters d'input optionnels peuvent être problématiques. Les procédures stockées qui effectuent des searchs sont de bons exemples.

L'une des manières les plus courantes d'écrire une telle requête dans SQL est avec plusieurs prédicats dans la clause where du formulaire (WHERE SomeColumn = @SomeVariable OR @SomeVariable IS NULL) . Bien que cela fonctionne, le problème est que cela fonctionne assez inefficacement. Sur les tables volumineuses, cela peut entraîner des performances de requête vraiment médiocres.

Souvent, une meilleure option consiste à utiliser sql dynamic paramétrée via sp_executesql . Consultez le blog de Catch-All Queries de Gail Shaw .