Справжнє запитання: Чи мають ці записи стосунки один до одного або стосунки один до багатьох ?
Відповідь TLDR:
Якщо один на один, використовуйте JOINвислів.
Якщо один-багато-багато, використовуйте один (або багато) SELECTоператорів з оптимізацією коду на стороні сервера.
Чому і як використовувати SELECT для оптимізації
SELECT'ing (з декількома запитами замість об'єднання) для великої групи записів на основі взаємозв'язку один до багатьох виробляє оптимальну ефективність, оскільки JOIN' ing має проблему експоненціальної витоку пам'яті. Візьміть усі дані, а потім скористайтеся мовою скриптів на стороні сервера, щоб впорядкувати їх:
SELECT * FROM Address WHERE Personid IN(1,2,3);
Результати:
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"
Ось, я отримую всі записи, в одному виділеному заяві. Це краще, ніж те JOIN, що отримувало б невелику групу цих записів, по одному, як підкомпонент іншого запиту. Потім я розбираю його з кодом на стороні сервера, який виглядає приблизно так ...
<?php
foreach($addresses as $address) {
$persons[$address['Personid']]->Address[] = $address;
}
?>
Коли не використовувати JOIN для оптимізації
JOIN'велика група записів, що базується на взаємозв'язку один на один з одним записом, забезпечує оптимальну ефективність порівняно з декількома SELECTвисловлюваннями, одна за одною, які просто отримують наступний тип запису.
Але JOINце неефективно при отриманні записів, які мають стосунки один до багатьох.
Приклад: Блоги в базі даних містять 3 цікаві таблиці, Blogpost, тег та коментар.
SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;
Якщо є 1 блог, 2 теги та 2 коментарі, ви отримаєте такі результати:
Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag2, comment1,
Row4: tag2, comment2,
Зауважте, як дублюється кожен запис. Гаразд, так, 2 коментарі та 2 теги - це 4 ряди. Що робити, якщо у нас є 4 коментарі та 4 теги? Ви не отримуєте 8 рядків - ви отримуєте 16 рядків:
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,
Додайте більше таблиць, більше записів і т. Д., І проблема швидко розгорнеться до сотень рядків, які наповнені переважно зайвими даними.
Скільки коштують ці дублікати? Пам'ять (на SQL-сервері та код, який намагається видалити дублікати) та мережеві ресурси (між SQL-сервером та сервером коду).
Джерело: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/uk/wb-relationship-tools.html