SQL เข้าร่วม vs ประสิทธิภาพ?


164

ฉันมีกรณีที่ใช้ JOIN หรือ IN จะให้ผลลัพธ์ที่ถูกต้อง ... ซึ่งโดยทั่วไปมีประสิทธิภาพที่ดีขึ้นและทำไม เท่าไหร่ก็ไม่ขึ้นอยู่กับสิ่งที่เซิร์ฟเวอร์ฐานข้อมูลที่คุณกำลังทำงานอยู่หรือไม่ (FYI ฉันใช้ MSSQL)


:) ฉันเป็นจริงมองหาบทความที่แตกต่างกันผมใช้เมื่อฉันวิจัยเป็นสิ่งที่คล้ายกันในขณะที่ที่ผ่านมาและเจอที่หนึ่งโดยไม่ได้ตั้งใจ
AdaTheDev

ขออภัยสำหรับล่อไปได้ ... ไม่พบคำถามว่าเมื่อฉันถูกค้นหา
Polaris878

คำตอบ:


197

พูดโดยทั่วไป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

หากคอลัมน์การเข้าร่วมเป็นและทำเครื่องหมายดังกล่าวทั้งคำสั่งเหล่านี้ผลผลิตในแผนเดียวกันUNIQUESQL Server

ถ้ามันไม่ได้แล้วINจะเร็วกว่าบนJOINDISTINCT

ดูบทความนี้ในบล็อกของฉันสำหรับรายละเอียดประสิทธิภาพ:


ใช่มันทำให้รู้สึกว่าพวกเขาจะดำเนินการเหมือนกันถ้าคอลัมน์การเข้าร่วมเป็นเอกลักษณ์ (ซึ่งมันเป็นในกรณีของฉัน)
Polaris878

1
เมื่อทราบเหมือนกันที่ฉันควรจะใช้ในการ (SELECT DISTINCT ... ) หรือเพียงแค่ IN (SELECT ... )?
หมู่

8
@ orlandu63: หมายถึงIN ฉลาดพอที่จะสังเกตเห็นมันและจะสร้างแผนเดียวกันสำหรับการค้นหาทั้ง ไม่แน่ใจว่าคนอื่นจะประพฤติอย่างไร DISTINCTSQL ServerRDBMS
Quassnoi

>> ในและเข้าร่วมเป็นแบบสอบถามที่แตกต่างกันที่สามารถให้ผลลัพธ์ที่แตกต่าง คุณช่วยกรุณาอธิบายว่าทำไมมันจะสร้างผลที่แตกต่างกันในกรณีนี้แม้ว่า b.col ไม่ซ้ำ?
Abhijeet



6

นั่นเป็นการยากที่จะบอกว่า - เพื่อที่จะค้นหาว่าอันไหนใช้ได้ดีกว่าคุณจะต้องกำหนดเวลาดำเนินการจริง

ในฐานะที่เป็นกฎทั่วไปของหัวแม่มือผมคิดว่าถ้าคุณมีดัชนีในคอลัมน์ต่างประเทศที่สำคัญของคุณและถ้าคุณกำลังใช้เท่านั้น (หรือส่วนใหญ่) INNER JOIN เงื่อนไขแล้ว JOIN จะเร็วขึ้นเล็กน้อย

แต่ทันทีที่คุณเริ่มใช้ OUTER JOIN หรือหากคุณไม่มีดัชนีคีย์ต่างประเทศระบบ IN อาจเร็วขึ้น

มาร์ค


ผมคิดว่านี้มากเกินไป ... เพราะดูเหมือนว่า JOIN เป็นกรณีที่พบบ่อยมากขึ้นและจะมีแนวโน้มที่จะเพิ่มประสิทธิภาพ
Polaris878

4

เขียนขึ้นน่าสนใจเกี่ยวกับความแตกต่างตรรกะ: SQL Server: JOIN VS IN VS EXISTS - ความแตกต่างเชิงตรรกะ

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

คุณต้องขอมันขึ้นอยู่กับ Query Analyzer แล้วลองและดูความแตกต่าง ดูที่แผนดำเนินการแบบสอบถามและพยายามลดขั้นตอนให้เล็กที่สุด


4

กระทู้นี้ค่อนข้างเก่า แต่ก็ยังพูดถึงบ่อย สำหรับรสชาติส่วนตัวของฉันมันเป็นบิตที่ไม่สมบูรณ์เพราะมีวิธีที่จะขอฐานข้อมูลที่มีอยู่คำหลักซึ่งผมพบว่าเป็นที่เร็วขึ้นไม่บ่อยกว่าอีก

ดังนั้นหากคุณสนใจเฉพาะค่าจากตาราง 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 เร็วขึ้นแล้วในแม้ว่าจะมีดัชนี ขึ้นอยู่กับระบบฐานข้อมูล (เครื่องมือเพิ่มประสิทธิภาพ) ข้อมูลและสุดท้ายไม่น้อยกว่าในประเภทของดัชนีที่ใช้


3
บน MSSql ความจริงที่มีอยู่ดีกว่าในดูเหมือนว่าไม่เป็นความจริง สำหรับข้อมูลเพิ่มเติม: explextended.com/2009/06/16/in-vs-join-vs-existsที่นี่คุณสามารถอ่านได้: "หลายคนคิดว่า EXISTS นั้นมีประสิทธิภาพมากกว่านั้นเพราะ EXISTS ส่งคืนเพียงแถวเดียวนี่คือ ไม่เป็นความจริงสำหรับ SQL Server ดังที่เราเห็นจากตัวอย่างข้างต้น EXISTS และ IN สร้างแผนเหมือนกันเพราะ EXISTS มีความยืดหยุ่นมากกว่า IN IN สามารถเขียนใหม่เป็น EXISTS ได้เสมอ (โดยใช้เงื่อนไข WHERE พร้อม equijoin ) แต่ไม่ใช่ในทางกลับกัน "
MicaëlFélix

3

การนำไปใช้ของแต่ละฐานข้อมูล แต่คุณสามารถเดาได้ว่าพวกเขาทั้งหมดแก้ปัญหาที่พบบ่อยในแบบเดียวกัน หากคุณใช้ MSSQL ให้ดูที่แผนการดำเนินการที่สร้างขึ้น คุณสามารถทำได้โดยการเปิด Profiler และการประหารชีวิตแผน สิ่งนี้จะให้เวอร์ชันของข้อความเมื่อคุณเรียกใช้คำสั่ง

ฉันไม่แน่ใจว่าคุณใช้ MSSQL รุ่นใด แต่คุณสามารถรับกราฟิกใน SQL Server 2000 ในตัววิเคราะห์คิวรีได้ ฉันแน่ใจว่าฟังก์ชันนี้ซุ่มซ่อนบางส่วนใน SQL Server Studio Manager ในรุ่นที่ใหม่กว่า

ดูที่แผน exeuction เท่าที่จะทำได้หลีกเลี่ยงการสแกนตารางยกเว้นว่าตารางของคุณมีขนาดเล็กซึ่งในกรณีนี้การสแกนตารางจะเร็วกว่าการใช้ดัชนี อ่านเกี่ยวกับการดำเนินการเข้าร่วมที่แตกต่างกันที่แต่ละสถานการณ์สร้าง


1

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


5
ควรทำ? อาจจะ. ทำมัน? ไม่เห็นโพสต์ของฉัน
cletus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.