118 votes

Est d'avoir un " OU " dans une JOINTURE INTERNE condition une mauvaise idée?

En essayant d'améliorer la vitesse d'une immense requête lente (plusieurs minutes sur les deux tableaux avec seulement environ 50 000 lignes chacun, sur SQL Server 2008 si c'est important), j'ai réduit le problème à un OR dans ma jointure interne, comme dans:

SELECT mt.ID, mt.ParentID, ot.MasterID
  FROM dbo.MainTable AS mt
  INNER JOIN dbo.OtherTable AS ot ON ot.ParentID = mt.ID
                                  OR ot.ID = mt.ParentID

J'ai changé cela (ce que j'espère, c'est) un équivalent de la paire de gauche rejoint, illustré ici:

SELECT mt.ID, mt.ParentID,
   CASE WHEN ot1.MasterID IS NOT NULL THEN
      ot1.MasterID ELSE
      ot2.MasterID END AS MasterID
  FROM dbo.MainTable AS mt
  LEFT JOIN dbo.OtherTable AS ot1 ON ot1.ParentID = mt.ID
  LEFT JOIN dbo.OtherTable AS ot2 ON ot2.ID = mt.ParentID
  WHERE ot1.MasterID IS NOT NULL OR ot2.MasterID IS NOT NULL

.. et que la requête s'exécute maintenant dans une deuxième!

C'est généralement une mauvaise idée de mettre un OR dans une condition de jointure? Ou suis-je tout simplement malchanceux en quelque sorte dans la mise en page de mes tables?

131voto

Quassnoi Points 191041

Ce genre d' JOIN n'est pas optimisable à un HASH JOIN ou MERGE JOIN.

Elle peut être exprimée comme une concaténation de deux jeux de résultats:

SELECT  *
FROM    maintable m
JOIN    othertable o
ON      o.parentId = m.id
UNION
SELECT  *
FROM    maintable m
JOIN    othertable o
ON      o.id = m.parentId

chacun d'entre eux étant une équi-jointure, cependant, SQL Servers'optimiseur n'est pas assez intelligent pour le voir dans la requête que vous avez écrit (même si elles sont logiquement équivalentes).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X