A verdadeira questão é: esses registros têm um relacionamento um para um ou um para muitos ?
Resposta TLDR:
Se um para um, use uma JOIN
declaração.
Se um para muitos, use uma (ou muitas) SELECT
instruções com a otimização de código do lado do servidor.
Por que e como usar o SELECT para otimização
SELECT
'(com várias consultas em vez de junções) em um grande grupo de registros com base em um relacionamento um para muitos produz uma eficiência ideal, pois JOIN
há um problema de vazamento de memória exponencial. Pegue todos os dados e use uma linguagem de script do lado do servidor para classificá-los:
SELECT * FROM Address WHERE Personid IN(1,2,3);
Resultados:
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"
Aqui, estou obtendo todos os registros, em uma instrução select. Isso é melhor que JOIN
, o que seria obter um pequeno grupo desses registros, um de cada vez, como subcomponente de outra consulta. Então eu o analiso com o código do servidor que se parece com ...
<?php
foreach($addresses as $address) {
$persons[$address['Personid']]->Address[] = $address;
}
?>
Quando não usar JOIN para otimização
JOIN
um grande grupo de registros com base em um relacionamento individual com um único registro produz uma eficiência ideal em comparação com várias SELECT
instruções, uma após a outra, que simplesmente obtêm o próximo tipo de registro.
Mas JOIN
é ineficiente ao obter registros com um relacionamento de um para muitos.
Exemplo: os blogs do banco de dados têm 3 tabelas de interesse, postagem no blog, tag e comentário.
SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;
Se houver 1 postagem no blog, 2 tags e 2 comentários, você obterá resultados como:
Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag2, comment1,
Row4: tag2, comment2,
Observe como cada registro é duplicado. Ok, então, 2 comentários e 2 tags são 4 linhas. E se tivermos 4 comentários e 4 tags? Você não tem 8 linhas - você tem 16 linhas:
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,
Adicione mais tabelas, mais registros, etc., e o problema aumentará rapidamente para centenas de linhas cheias de dados principalmente redundantes.
Quanto custam essas duplicatas? Memória (no servidor SQL e o código que tenta remover as duplicatas) e recursos de rede (entre o servidor SQL e o servidor de código).
Fonte: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html