Câu hỏi thực sự là: Những hồ sơ này có mối quan hệ một đối một hay mối quan hệ một -nhiều ?
Trả lời TLDR:
Nếu một đối một, sử dụng một JOIN
tuyên bố.
Nếu một-nhiều, sử dụng một (hoặc nhiều) SELECT
câu lệnh với tối ưu hóa mã phía máy chủ.
Tại sao và làm thế nào để sử dụng CHỌN để tối ưu hóa
SELECT
'ing (với nhiều truy vấn thay vì tham gia) trên một nhóm lớn các bản ghi dựa trên mối quan hệ một-nhiều tạo ra hiệu quả tối ưu, vì JOIN
' ing có vấn đề rò rỉ bộ nhớ theo cấp số nhân. Lấy tất cả dữ liệu, sau đó sử dụng ngôn ngữ kịch bản phía máy chủ để sắp xếp nó:
SELECT * FROM Address WHERE Personid IN(1,2,3);
Các kết quả:
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"
Ở đây, tôi nhận được tất cả các hồ sơ, trong một tuyên bố chọn. Điều này tốt hơn là JOIN
, sẽ lấy một nhóm nhỏ các bản ghi này, từng bản một, làm thành phần phụ của một truy vấn khác. Sau đó, tôi phân tích nó bằng mã phía máy chủ trông giống như ...
<?php
foreach($addresses as $address) {
$persons[$address['Personid']]->Address[] = $address;
}
?>
Khi không sử dụng THAM GIA để tối ưu hóa
JOIN
'một nhóm lớn các bản ghi dựa trên mối quan hệ một đối một với một bản ghi duy nhất tạo ra hiệu quả tối ưu so với nhiều SELECT
câu lệnh, lần lượt từng câu lệnh, chỉ đơn giản là có được loại bản ghi tiếp theo.
Nhưng JOIN
không hiệu quả khi nhận hồ sơ với mối quan hệ một-nhiều.
Ví dụ: Blog cơ sở dữ liệu có 3 bảng quan tâm, Blogpost, Tag và Comment.
SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;
Nếu có 1 blogpost, 2 thẻ và 2 bình luận, bạn sẽ nhận được kết quả như sau:
Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag2, comment1,
Row4: tag2, comment2,
Lưu ý cách mỗi bản ghi được nhân đôi. Được rồi, vì vậy, 2 bình luận và 2 thẻ là 4 hàng. Nếu chúng ta có 4 bình luận và 4 thẻ thì sao? Bạn không nhận được 8 hàng - bạn nhận được 16 hàng:
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,
Thêm nhiều bảng hơn, nhiều bản ghi hơn, v.v., và vấn đề sẽ nhanh chóng tăng lên hàng trăm hàng chứa đầy đủ dữ liệu chủ yếu .
Những gì trùng lặp chi phí bạn? Bộ nhớ (trong máy chủ SQL và mã cố gắng loại bỏ các bản sao) và tài nguyên mạng (giữa máy chủ SQL và máy chủ mã của bạn).
Nguồn: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html