2009-12-08 3 views
5

Si je me joins à la table A à la table B comme ça ...Est-ce que SQL Server regarde même une table lors d'une jointure sur une variable qui retourne false?

select A.* from A 
left outer join B on A.Id = B.aId and @param = 'someValue' 

et @param ne correspond pas à « someValue », SQL Server ne même tenter de faire correspondre les enregistrements de la table B ou est assez intelligent pour savoir la condition ne sera jamais vraie?

+0

Pourquoi le feriez-vous jamais? Ou est-ce juste un hypothétique? –

+0

J'essayais de trouver un moyen efficace d'écrire une requête dont les critères pouvaient exister dans 1 des 15 tables différentes en fonction d'un paramètre qui indiquait quelle table. – adam0101

+0

On dirait que c'est votre problème de racine et c'est juste un symptôme de cela. Quel type de requête couvre 15 entités différentes? –

Répondre

7

Ainsi, alors que dans un contexte particulier, vous pouvez constater que le quand @param a une valeur différente, alors la table de jointure externe ne peut jamais être sondé, vous ne devriez pas compter sur elle pour l'exactitude. Notez que probe signifie que les valeurs réelles sont recherchées dans la table. Les informations sur les métadonnées seront toujours être vérifiées. Par exemple, vous ne pouvez pas tricher et demander une jointure à une table qui n'existe pas.

En particulier, n'essayez pas de créer une seule requête où il devrait y avoir deux requêtes différentes (une qui se joint, une qui ne l'est pas).

+0

Réponse impressionnante! – cdonner

1

Il est plus facile de mettre ce code dans une nouvelle réponse plutôt que d'un commentaire, mais cela montre un peu de ce que Remus dit:

CREATE PROCEDURE dbo.Test_Params 
    @param1 INT 
WITH RECOMPILE 
AS 
BEGIN 
    SELECT 
     o.object_id, 
     c.object_id 
    FROM 
     sys.objects o 
    LEFT OUTER JOIN sys.columns c ON 
     c.object_id = o.object_id AND 
     @param1 = 1 
    OPTION 
     (RECOMPILE) 
END 
GO 


EXEC dbo.Test_Params 1 
EXEC dbo.Test_Params 2 

Si vous faites un plan d'exécution sur les deux déclarations EXEC, vous verra que sys.columns apparaît dans les deux plans d'exécution, mais dans la seconde, les lignes sont toutes filtrées avant que la jointure ait lieu. Notez cependant qu'ils ne sont pas court-circuités complètement hors de la requête.

Questions connexes