web-dev-qa-db-fra.com

Quel est le meilleur: beaucoup de conditions d'adhésion ou beaucoup de conditions?

J'essaie de comparer deux requêtes:

Requête 1:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a
WHERE tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  AND tableA.e=tableB.e 

Requête 2:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a AND tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  
WHERE tableA.e=tableB.e 

Ai-je raison de dire que ces deux requêtes donnent les mêmes résultats?

De plus, est-il correct de dire que la première requête crée une table plus grande pour laquelle effectuer une condition WHERE plus grande; tandis que le deuxième cas, nous avons une table construite plus petite à laquelle le simple WHERE est ensuite appliqué.

En supposant que les résultats sont les mêmes, quelle requête doit être préférée? Y a-t-il un problème de performance évident?

14
Geoff

Si nous considérons que vous utilisez INNER JOIN au lieu de LEFT JOIN (ce qui semble être votre intention), ces deux requêtes sont fonctionnellement équivalentes. Les optimiseurs de requête examineront et évalueront les critères de votre clause WHERE et de votre clause FROM et prendront en compte tous ces facteurs lors de la création de plans de requête afin d'atteindre le plan d'exécution le plus efficace. Si nous faisons un EXPLAIN sur les deux instructions, nous obtenons le même résultat:

Requête 1 :

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
WHERE 
  tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
  AND tableA.ColE=tableB.ColE

[Résultats] :

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

Requête 2 :

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
  AND tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
WHERE
  tableA.ColE=tableB.ColE

[Résultats] :

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

Vous pouvez consulter tous les détails avec les liens suivants. J'ai également créé un exemple SQL 2008 afin que vous puissiez comparer le fonctionnement des deux moteurs (qui est le même):

exemple de requête MySQL

exemple de requête SQL 2008 (Assurez-vous que vous "Afficher le plan d'exécution" pour les deux résultats)

10
Mike Fal