MySQL: การเข้าร่วมใดดีกว่าระหว่างการเข้าร่วมด้านนอกด้านซ้ายและการเข้าร่วมภายใน


11

การเข้าร่วมใดจะดีกว่าการแสดงผลหากพวกเขาทั้งหมดให้ผลลัพธ์เดียวกัน ตัวอย่างเช่นผมมีสองตารางและemployees(emp_id,name, address, designation, age, sex) work_log(emp_id,date,hours_wored)เพื่อให้ได้ผลลัพธ์ที่เฉพาะเจาะจงทั้งสองinner joinและleft joinให้ผลลัพธ์เดียวกัน แต่ฉันยังมีข้อสงสัยบางอย่างที่ไม่ จำกัด เฉพาะคำถามนี้เท่านั้น

  • การเข้าร่วมใดที่มีประสิทธิภาพมากกว่าซึ่งควรเลือกในกรณีที่มีค่าผลลัพธ์เดียวกัน
  • ปัจจัยอื่น ๆ ที่ต้องพิจารณาในเวลาที่สมัครเข้าร่วมมีอะไรบ้าง
  • มีความสัมพันธ์ระหว่างการเข้าร่วมภายในกับการเข้าร่วมไขว้ไหม?

คำตอบ:


15

ไม่มีประเภทการเข้าร่วมที่ "ดีกว่า" หรือ "แย่ลง" พวกเขามีความหมายที่แตกต่างกันและพวกเขาจะต้องใช้ขึ้นอยู่กับมัน

ในกรณีของคุณคุณอาจไม่มีพนักงานที่ไม่มี work_log (ไม่มีแถวในตารางนั้น) ดังนั้นLEFT JOINและJOINจะเทียบเท่าในผลลัพธ์ อย่างไรก็ตามหากคุณมีสิ่งดังกล่าว (พนักงานใหม่ที่ไม่มี work_log ที่ลงทะเบียนแล้ว) ทุ่งจะJOINละเว้นพนักงานคนนั้นในขณะที่การเข้าร่วมด้านซ้าย (ซึ่งตารางแรกเป็นพนักงาน) จะแสดงทั้งหมดและ null ในฟิลด์จาก work_log หากมี ไม่ตรงกัน

คำอธิบายแบบภาพของประเภท JOIN

อีกครั้งประสิทธิภาพเป็นสิ่งที่รองเพื่อค้นหาความถูกต้อง บางคนบอกว่าคุณไม่ควรใช้LEFT JOINของ มันเป็นความจริงที่ LEFT JOIN บังคับให้เครื่องมือเพิ่มประสิทธิภาพเพื่อดำเนินการค้นหาในลำดับหนึ่งโดยเฉพาะเพื่อป้องกันการเพิ่มประสิทธิภาพบางอย่าง (การจัดตารางใหม่) ในบางกรณี นี่คือตัวอย่างหนึ่ง แต่คุณไม่ควรเลือกอย่างใดอย่างหนึ่งหากความถูกต้อง / ความหมายถูกเสียสละเป็น INNER JOIN ไม่เลวโดยเนื้อแท้ ส่วนที่เหลือของการปรับให้เหมาะสมตามปกติจะใช้ตามปกติ

โดยสรุปไม่ได้ใช้ถ้าคุณหมายถึงจริงๆLEFT JOININNER JOIN

ใน MySQL CROSS JOIN, INNER JOINและJOINจะเหมือนกัน ในมาตรฐานและ semantically a CROSS JOINคือa INNER JOINโดยไม่มีส่วนONคำสั่งดังนั้นคุณจะได้รับทุกชุดของแถวระหว่างตาราง

คุณมีตัวอย่างของทุกประเภทความหมายของการเข้าร่วมในวิกิพีเดีย ในทางปฏิบัติใน MySQL เรามักจะเขียนเท่านั้นและJOINLEFT JOIN


1
คำอธิบาย Gr8 @jynus โชคดีที่ฉันได้รับคำตอบสำหรับคำถามของฉันจากคุณเท่านั้น
ursitesion

1 กราฟิกที่เกี่ยวข้องนั้นดีกว่า 1,000 คำ คุณทำมันได้หรือ
Fr0zenFyr

ไม่ฉันไม่ได้ระบุแหล่งที่มาที่ด้านล่างของรูปcodeproject.com/Articles/33052/… - แม้ว่าการใช้ venn diagrams เพื่อเป็นตัวแทนของ joins นั้นเก่าแก่พอ ๆ กับพีชคณิตแบบเป็นทางการ: en.wikipedia.org/wiki/Relational_algebra
jynus

ฉันเริ่มจากชุดความคิดเห็นจากนั้นฉันก็รู้ว่าทุกอย่างจะไปถึง - มันขึ้นอยู่กับคำถามของคุณ +1 จากฉัน!
iheanyi


0

การเข้าร่วมใดที่จะทำงานได้ดีขึ้นหากพวกเขาทั้งหมดให้ผลลัพธ์เดียวกัน

ฉันเพิ่มคำตอบก่อนหน้าสำหรับสิ่งที่ฉันรู้ MySQL ได้รับการปรับปรุงให้มีประสิทธิภาพเดียวกัน

ด้วยดัชนีที่ดีตัวอย่างเช่นJOINvs LEFT JOIN+ WHEREclause to filter จะเป็นสิ่งเดียวกัน การปรับให้เหมาะสมกับการอ่านของมนุษย์นั้นให้ความสำคัญกับข้อความค้นหาจำนวนมากที่มีการรวมจำนวนมาก

การใช้ดัชนีและแคชที่ดีนั้นสำคัญมาก

คุณสามารถอ่านคำอธิบายที่ดีของกระบวนการเพิ่มประสิทธิภาพได้ที่นี่:

กระบวนการปรับให้เหมาะสมของแบบสอบถาม : แบบสอบถามสามารถดำเนินการได้หลายวิธีและสร้างผลลัพธ์เดียวกัน งานของเครื่องมือเพิ่มประสิทธิภาพคือการหาตัวเลือกที่ดีที่สุด


0

มันไม่เหมือนกันสำหรับฉัน MySql 5.7 8 vCPU, 52 GB RAM

แบบสอบถามต่อไปนี้ใช้เวลา ~ 30 วินาทีไม่แน่ใจว่าทำไม

ตารางธุรกรรมมี 24,257,151 บันทึก

ตารางกิจกรรมมี 18,603,665 บันทึก

ตารางการซื้อมีบันทึก 13,911,705 รายการ

ดัชนีที่จำเป็นทั้งหมดอยู่ในสถานที่

SELECT
    `trx`.`transaction_pk`,
    `trx`.`created`,
    `trx`.`updated`,
    `p`.`amount`,
    `trxst`.`name`,
    COALESCE ( a.units, 0 ) AS units
FROM
    `transaction` AS `trx`
    INNER JOIN `transaction_sub_type` AS `trxst` ON  `trx`.`transaction_sub_type_fk`= `trxst`.`transaction_sub_type_pk`
    left JOIN `activity` AS `a` ON `a`.`transaction_fk` = `trx`.`transaction_pk`
    LEFT JOIN `purchases` AS `p` ON `p`.`transaction_fk` = `trx`.`transaction_pk` 
WHERE
    `trx`.`entity_fk` IN ( 1234) 
    AND `trx`.`transaction_sub_type_fk` IN (
    2, 4, 5, 15, 16, 33, 37, 38, 85, 86, 87, 88, 102, 103 
    ) 
ORDER BY
    `trx`.`transaction_pk` DESC LIMIT 100 OFFSET 0;

หลังจากเปลี่ยนบรรทัดต่อไปนี้:

INNER JOIN `transaction_sub_type` AS `trxst` ON  `trx`.`transaction_sub_type_fk`= `trxst`.`transaction_sub_type_pk`

ด้วยซ้ายเข้าร่วม

LEFT JOIN `transaction_sub_type` AS `trxst` ON  `trx`.`transaction_sub_type_fk`= `trxst`.`transaction_sub_type_pk`

แบบสอบถามเดียวกันใช้เวลาประมาณ 0.046 วินาที

อธิบายก่อน:

1   SIMPLE  trxst       ALL PRIMARY             101 37.62   Using where; Using temporary; Using filesort
1   SIMPLE  trx     ref transaction_sub_type_fk,entity_fk   transaction_sub_type_fk 4   trxst.transaction_sub_type_pk   2548    0.36    Using where
1   SIMPLE  a       ref transaction_fk  transaction_fk  4   trx.transaction_pk  1   100 
1   SIMPLE  p       ref transaction_fk  transaction_fk  4   trx.transaction_pk  1   100 

อธิบายหลังจาก:

1   SIMPLE  trx     ref transaction_sub_type_fk,entity_fk   entity_fk   4   const   81474   83.65   Using where
1   SIMPLE  trxst       eq_ref  PRIMARY PRIMARY 4   trx.transaction_sub_type_fk 1   100 
1   SIMPLE  a       ref transaction_fk  transaction_fk  4   trx.transaction_pk  1   100 
1   SIMPLE  p       ref transaction_fk  transaction_fk  4   trx.transaction_pk  1   100 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.