La première syntaxe est généralement plus efficace.
MySQL
buffers les requêtes dérivées de sorte que l'utilisation de la requête dérivée prive le user_profile
de possibilité d'être une table pilotée dans la jointure.
Même si le user_profile
est en tête, les résultats des sous-requêtes doivent être mises en mémoire tampon premier qui implique un impact de la mémoire et de performance.
A LIMIT
appliqué aux requêtes fera la première requête beaucoup plus rapide qui est pas vrai pour le second.
Voici les plans d'échantillonnage. Il y a un index sur (val, nid)
dans le tableau t_source
:
première requête:
EXPLAIN
SELECT *
FROM t_source s1
JOIN t_source s2
ON s2.nid = s1.id
WHERE s2.val = 1
1, 'SIMPLE', 's1', 'ALL', 'PRIMARY', '', '', '', 1000000, ''
1, 'SIMPLE', 's2', 'ref', 'ix_source_val,ix_source_val_nid,ix_source_vald_nid', 'ix_source_val_nid', '8', 'const,test.s1.id', 1, 'Using where'
seconde requête:
EXPLAIN
SELECT *
FROM t_source s1
JOIN (
SELECT nid
FROM t_source s2
WHERE val = 1
) q
ON q.nid = s1.id
1, 'PRIMARY', '<derived2>', 'ALL', '', '', '', '', 100000, ''
1, 'PRIMARY', 's1', 'ref', 'PRIMARY', 'PRIMARY', '4', 'q.nid', 10000, 'Using where'
2, 'DERIVED', 's2', 'ref', 'ix_source_val,ix_source_val_nid,ix_source_vald_nid', 'ix_source_vald_nid', '4', '', 91324, 'Using index'
Comme vous pouvez le voir, seule une partie de l'indice est utilisé dans la deuxième cas, et q
est forcé d'être en tête.
Mise à jour:
requêtes dérivées (ce qui est ce que cela concerne la question) ne doivent pas être confondus avec les sous-requêtes.
Alors que MySQL
n'est pas en mesure d'optimiser les requêtes dérivées (celles qui sont utilisées dans la clause FROM
), les (ceux des sous-requêtes utilisées avec IN
ou EXISTS
) sont beaucoup mieux traités.
Voir ces articles dans mon blog pour plus de détails:
Je serais curieux de connaître la différence entre 2 et cette requête, ou, s'il y aurait une différence: Choisissez le nom dans utilisateur où uid IN (SELECT uid DE user_profile WHERE adresse = 'une constante'); – Drew
EXPLIQUEZ les deux? Je suppose que le premier car je n'ai jamais vu une grande performance des sous-sélections dans MySQL. –