La vraie question est: ces enregistrements ont -ils une relation un-à-un ou une relation un-à-plusieurs ?
Réponse TLDR:
S'il s'agit d'un à un, utilisez une JOIN
instruction.
S'il s'agit d'un à plusieurs, utilisez une (ou plusieurs) SELECT
instructions avec l'optimisation du code côté serveur.
Pourquoi et comment utiliser SELECT pour l'optimisation
SELECT
'ing (avec plusieurs requêtes au lieu de jointures) sur un grand groupe d'enregistrements basé sur une relation un-à-plusieurs produit une efficacité optimale, car JOIN
' ing a un problème de fuite de mémoire exponentielle. Saisissez toutes les données, puis utilisez un langage de script côté serveur pour les trier:
SELECT * FROM Address WHERE Personid IN(1,2,3);
Résultats:
Address.id : 1 // First person and their address
Address.Personid : 1
Address.City : "Boston"
Address.id : 2 // First person's second address
Address.Personid : 1
Address.City : "New York"
Address.id : 3 // Second person's address
Address.Personid : 2
Address.City : "Barcelona"
Ici, je reçois tous les enregistrements, dans une seule instruction select. C'est mieux que JOIN
, qui obtiendrait un petit groupe de ces enregistrements, un à la fois, en tant que sous-composant d'une autre requête. Ensuite, je l'analyse avec un code côté serveur qui ressemble à quelque chose comme ...
<?php
foreach($addresses as $address) {
$persons[$address['Personid']]->Address[] = $address;
}
?>
Quand ne pas utiliser JOIN pour l'optimisation
JOIN
Un grand groupe d'enregistrements basé sur une relation biunivoque avec un seul enregistrement produit une efficacité optimale par rapport à plusieurs SELECT
instructions, l'une après l'autre, qui obtiennent simplement le type d'enregistrement suivant.
Mais JOIN
est inefficace lors de l'obtention d'enregistrements avec une relation un-à-plusieurs.
Exemple: La base de données Blogs a 3 tables d'intérêt, Blogpost, Tag et Comment.
SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;
S'il y a 1 article de blog, 2 balises et 2 commentaires, vous obtiendrez des résultats comme:
Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag2, comment1,
Row4: tag2, comment2,
Remarquez comment chaque enregistrement est dupliqué. Bon, donc, 2 commentaires et 2 balises font 4 lignes. Et si nous avons 4 commentaires et 4 balises? Vous n'obtenez pas 8 lignes - vous obtenez 16 lignes:
Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag1, comment3,
Row4: tag1, comment4,
Row5: tag2, comment1,
Row6: tag2, comment2,
Row7: tag2, comment3,
Row8: tag2, comment4,
Row9: tag3, comment1,
Row10: tag3, comment2,
Row11: tag3, comment3,
Row12: tag3, comment4,
Row13: tag4, comment1,
Row14: tag4, comment2,
Row15: tag4, comment3,
Row16: tag4, comment4,
Ajoutez plus de tables, plus d'enregistrements, etc., et le problème augmentera rapidement à des centaines de lignes qui sont toutes pleines de données pour la plupart redondantes.
Combien vous coûtent ces doublons? Mémoire (dans le serveur SQL et le code qui tente de supprimer les doublons) et ressources réseau (entre le serveur SQL et votre serveur de code).
Source: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html