คำถามที่แท้จริงคือ: บันทึกเหล่านี้มีความสัมพันธ์แบบหนึ่งต่อหนึ่งหรือความสัมพันธ์แบบหนึ่งต่อหลายคนหรือไม่?
คำตอบ TLDR:
หากหนึ่งต่อหนึ่งใช้JOIN
คำสั่ง
หากคำสั่งแบบตัวต่อตัวใช้หนึ่งSELECT
คำสั่ง(หรือหลายคำสั่ง) พร้อมการปรับแต่งโค้ดฝั่งเซิร์ฟเวอร์
ทำไมและวิธีใช้ SELECT เพื่อการปรับให้เหมาะสม
SELECT
'อิง (มีหลายแบบสอบถามแทนการเข้าร่วม) ในกลุ่มระเบียนขนาดใหญ่โดยยึดตามความสัมพันธ์แบบหนึ่งต่อหลายคนทำให้เกิดประสิทธิภาพสูงสุดเนื่องจาก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
การใช้กลุ่มระเบียนขนาดใหญ่โดยอิงตามความสัมพันธ์แบบหนึ่งต่อหนึ่งกับระเบียนเดียวจะให้ประสิทธิภาพที่ดีที่สุดเมื่อเปรียบเทียบกับหลาย ๆSELECT
ข้อความซึ่งเป็นข้อมูลประเภทถัดไป
แต่JOIN
ไม่มีประสิทธิภาพในการรับบันทึกที่มีความสัมพันธ์แบบหนึ่งต่อหลายคน
ตัวอย่าง: บล็อกฐานข้อมูลมี 3 ตารางที่น่าสนใจ Blogpost, Tag และข้อคิดเห็น
SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;
หากมี 1 blogpost, 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/en/wb-relationship-tools.html