ฉันมีกรณีที่ใช้ JOIN หรือ IN จะให้ผลลัพธ์ที่ถูกต้อง ... ซึ่งโดยทั่วไปมีประสิทธิภาพที่ดีขึ้นและทำไม เท่าไหร่ก็ไม่ขึ้นอยู่กับสิ่งที่เซิร์ฟเวอร์ฐานข้อมูลที่คุณกำลังทำงานอยู่หรือไม่ (FYI ฉันใช้ MSSQL)
ฉันมีกรณีที่ใช้ JOIN หรือ IN จะให้ผลลัพธ์ที่ถูกต้อง ... ซึ่งโดยทั่วไปมีประสิทธิภาพที่ดีขึ้นและทำไม เท่าไหร่ก็ไม่ขึ้นอยู่กับสิ่งที่เซิร์ฟเวอร์ฐานข้อมูลที่คุณกำลังทำงานอยู่หรือไม่ (FYI ฉันใช้ MSSQL)
คำตอบ:
พูดโดยทั่วไปIN
และJOIN
เป็นข้อความค้นหาที่แตกต่างกันซึ่งสามารถให้ผลลัพธ์ที่แตกต่างกัน
SELECT a.*
FROM a
JOIN b
ON a.col = b.col
ไม่เหมือนกัน
SELECT a.*
FROM a
WHERE col IN
(
SELECT col
FROM b
)
ยกเว้นในกรณีที่b.col
ไม่ซ้ำกัน
อย่างไรก็ตามนี่คือคำพ้องความหมายสำหรับแบบสอบถามแรก:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT col
FROM b
)
ON b.col = a.col
หากคอลัมน์การเข้าร่วมเป็นและทำเครื่องหมายดังกล่าวทั้งคำสั่งเหล่านี้ผลผลิตในแผนเดียวกันUNIQUE
SQL Server
ถ้ามันไม่ได้แล้วIN
จะเร็วกว่าบนJOIN
DISTINCT
ดูบทความนี้ในบล็อกของฉันสำหรับรายละเอียดประสิทธิภาพ:
IN
ฉลาดพอที่จะสังเกตเห็นมันและจะสร้างแผนเดียวกันสำหรับการค้นหาทั้ง ไม่แน่ใจว่าคนอื่นจะประพฤติอย่างไร DISTINCT
SQL Server
RDBMS
ตลกที่คุณพูดถึงว่าฉันโพสต์บล็อกในเรื่องนี้มาก
ดูออราเคิล VS MySQL VS SQL Server: รวม VS ร่วม
คำตอบสั้น ๆ : คุณต้องทดสอบและแต่ละฐานข้อมูลมีความแตกต่างกันมาก
นั่นเป็นการยากที่จะบอกว่า - เพื่อที่จะค้นหาว่าอันไหนใช้ได้ดีกว่าคุณจะต้องกำหนดเวลาดำเนินการจริง
ในฐานะที่เป็นกฎทั่วไปของหัวแม่มือผมคิดว่าถ้าคุณมีดัชนีในคอลัมน์ต่างประเทศที่สำคัญของคุณและถ้าคุณกำลังใช้เท่านั้น (หรือส่วนใหญ่) INNER JOIN เงื่อนไขแล้ว JOIN จะเร็วขึ้นเล็กน้อย
แต่ทันทีที่คุณเริ่มใช้ OUTER JOIN หรือหากคุณไม่มีดัชนีคีย์ต่างประเทศระบบ IN อาจเร็วขึ้น
มาร์ค
เขียนขึ้นน่าสนใจเกี่ยวกับความแตกต่างตรรกะ: SQL Server: JOIN VS IN VS EXISTS - ความแตกต่างเชิงตรรกะ
ฉันค่อนข้างมั่นใจว่าสมมติว่าความสัมพันธ์และดัชนีได้รับการดูแลให้เข้าร่วมจะมีประสิทธิภาพโดยรวมที่ดีขึ้น (ความพยายามมากขึ้นในการทำงานกับการดำเนินการนั้นและอื่น ๆ ) หากคุณคิดเกี่ยวกับแนวคิดแล้วความแตกต่างระหว่าง 2 แบบสอบถามและ 1 แบบสอบถาม
คุณต้องขอมันขึ้นอยู่กับ Query Analyzer แล้วลองและดูความแตกต่าง ดูที่แผนดำเนินการแบบสอบถามและพยายามลดขั้นตอนให้เล็กที่สุด
กระทู้นี้ค่อนข้างเก่า แต่ก็ยังพูดถึงบ่อย สำหรับรสชาติส่วนตัวของฉันมันเป็นบิตที่ไม่สมบูรณ์เพราะมีวิธีที่จะขอฐานข้อมูลที่มีอยู่คำหลักซึ่งผมพบว่าเป็นที่เร็วขึ้นไม่บ่อยกว่าอีก
ดังนั้นหากคุณสนใจเฉพาะค่าจากตาราง a คุณสามารถใช้แบบสอบถามนี้:
SELECT a.*
FROM a
WHERE EXISTS (
SELECT *
FROM b
WHERE b.col = a.col
)
ความแตกต่างอาจมีขนาดใหญ่ถ้า col ไม่ได้จัดทำดัชนีเนื่องจาก db ไม่จำเป็นต้องค้นหาระเบียนทั้งหมดใน b ซึ่งมีค่าเท่ากันใน col มันจะต้องค้นหาระเบียนแรกเท่านั้น หากไม่มีดัชนีใน b.col และบันทึกจำนวนมากในการสแกนตาราง ba อาจเป็นผลที่ตามมา ด้วย IN หรือ JOIN การสแกนแบบเต็มตารางด้วย EXISTS จะเป็นการสแกนตารางเพียงบางส่วน (จนกว่าจะพบระเบียนแรกที่ตรงกัน)
หากมีเร็กคอร์ดจำนวนมากใน b ซึ่งมีค่า col เท่ากันคุณจะสูญเสียหน่วยความจำจำนวนมากสำหรับการอ่านเร็กคอร์ดเหล่านี้ทั้งหมดในพื้นที่ชั่วคราวเพื่อค้นหาว่าสภาพของคุณเป็นที่น่าพอใจ ด้วยที่มีอยู่นี้มักจะสามารถหลีกเลี่ยงได้
ฉันมักจะพบ EXISTS เร็วขึ้นแล้วในแม้ว่าจะมีดัชนี ขึ้นอยู่กับระบบฐานข้อมูล (เครื่องมือเพิ่มประสิทธิภาพ) ข้อมูลและสุดท้ายไม่น้อยกว่าในประเภทของดัชนีที่ใช้
การนำไปใช้ของแต่ละฐานข้อมูล แต่คุณสามารถเดาได้ว่าพวกเขาทั้งหมดแก้ปัญหาที่พบบ่อยในแบบเดียวกัน หากคุณใช้ MSSQL ให้ดูที่แผนการดำเนินการที่สร้างขึ้น คุณสามารถทำได้โดยการเปิด Profiler และการประหารชีวิตแผน สิ่งนี้จะให้เวอร์ชันของข้อความเมื่อคุณเรียกใช้คำสั่ง
ฉันไม่แน่ใจว่าคุณใช้ MSSQL รุ่นใด แต่คุณสามารถรับกราฟิกใน SQL Server 2000 ในตัววิเคราะห์คิวรีได้ ฉันแน่ใจว่าฟังก์ชันนี้ซุ่มซ่อนบางส่วนใน SQL Server Studio Manager ในรุ่นที่ใหม่กว่า
ดูที่แผน exeuction เท่าที่จะทำได้หลีกเลี่ยงการสแกนตารางยกเว้นว่าตารางของคุณมีขนาดเล็กซึ่งในกรณีนี้การสแกนตารางจะเร็วกว่าการใช้ดัชนี อ่านเกี่ยวกับการดำเนินการเข้าร่วมที่แตกต่างกันที่แต่ละสถานการณ์สร้าง
เครื่องมือเพิ่มประสิทธิภาพควรฉลาดพอที่จะให้ผลลัพธ์เหมือนกันทั้งสองวิธีสำหรับข้อความค้นหาปกติ ตรวจสอบแผนปฏิบัติการและพวกเขาควรจะให้คุณในสิ่งเดียวกัน หากพวกเขาทำไม่ได้ฉันจะถือว่า JOIN นั้นเร็วกว่าปกติ อย่างไรก็ตามระบบทั้งหมดนั้นแตกต่างกันดังนั้นคุณควรทำการกำหนดรหัสบนระบบของคุณเพื่อให้แน่ใจ