จัดทำดัชนีประสิทธิภาพการทำงานเป็นเปิดเมื่อเทียบกับตำแหน่งที่


26

ฉันมีสองตาราง

@T1 TABLE
(
    Id INT,
    Date DATETIME
)

@T2 TABLE
(
    Id INT,
    Date DATETIME
)

ตารางเหล่านี้มีดัชนีที่ไม่ทำคลัสเตอร์ (Id, Date)

และฉันเข้าร่วมตารางเหล่านี้

SELECT *
FROM T1 AS t1
INNER JOIN T2 AS t2
ON 
    t1.Id = t2.Id
WHERE 
    t1.Date <= GETDATE()
    AND
    t2.Date <= GETDATE()

สิ่งนี้สามารถเขียนเป็น

SELECT *
FROM T1 AS t1
INNER JOIN T2 AS t2
ON 
    t1.Id = t2.Id
    AND
    t1.Date <= GETDATE()
    AND
    t2.Date <= GETDATE()

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


1
คุณมีตัวแปร @table จริง ๆ ที่มีดัชนีที่ไม่ใช่คลัสเตอร์ซึ่งครอบคลุมทุกฟิลด์และไม่มีดัชนีที่ทำคลัสเตอร์หรือไม่ หรือเป็นเพียงการทำให้เข้าใจง่าย?
Remus Rusanu

1
มันเป็นความเรียบง่ายมาก
เอริค Bergstedt

คำตอบ:


32

ประสิทธิภาพจะเหมือนกัน เครื่องมือเพิ่มประสิทธิภาพจะรับรู้สิ่งนี้และสร้างแผนเดียวกัน

ในทางกลับกันฉันจะไม่พูดว่าพวกเขาเท่ากัน แบบฟอร์มแรกของคำถามนั้นอ่านได้ง่ายกว่าและคาดหวังโดยทั่วไป

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

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

SELECT * FROM salestable , custtable 
WHERE salestable.custaccount = custtable.accountnum 
AND salestable.dataareaid = custtable.dataareaid

SELECT * FROM salestable 
JOIN  custtable 
ON salestable.custaccount = custtable.accountnum 
AND salestable.dataareaid = custtable.dataareaid

SELECT * FROM salestable JOIN custtable 
ON salestable.custaccount = custtable.accountnum 
WHERE salestable.dataareaid = custtable.dataareaid

ให้แผนปฏิบัติการเหล่านี้

ป้อนคำอธิบายรูปภาพที่นี่


ฉันเห็นด้วยรูปแบบแรกอ่านง่ายกว่าและฉันก็โล่งใจว่ามันเท่ากัน ฉันจะใช้แบบฟอร์มนี้ในอนาคตเท่านั้น
Erik Bergstedt

@ErikBergstedt ฉันแก้ไขคำตอบของฉันคุณควรจะสามารถตรวจสอบสิ่งนี้สำหรับชุดข้อมูลและโครงสร้างตารางของคุณเองได้อย่างง่ายดายเมื่อคุณดูแผนการดำเนินการ
Tom V - ทีม Monica

ใช่ฉันทำ. ขอขอบคุณ. ฉันแค่มองหาความคิดเห็นที่ 2 เนื่องจากฉันไม่พบคำตอบที่มีอยู่
Erik Bergstedt

หมายเหตุ: INNER JOINพวกเขาเป็นเพียงเท่ากันถ้ามันเป็น หากคุณโยนOUTER JOINเข้าไปแล้วพวกเขาจะไม่เหมือนกันอย่างแน่นอน
Kenneth Fisher

22

พวกเขาเหมือนกันในเชิงความหมายและผู้เพิ่มประสิทธิภาพไม่ควรมีปัญหาในการรับรู้ข้อเท็จจริงนี้และสร้างแผนการที่เหมือนกัน

ฉันมักจะใส่เงื่อนไขอ้างอิงตารางทั้งในและเงื่อนไขอ้างอิงเพียงหนึ่งตารางในONWHERE

สำหรับการOUTER JOINSย้ายเงื่อนไขอาจมีผลต่อความหมายอย่างไรก็ตาม


7

ในกรณีง่าย ๆ มันจะเหมือนกัน อย่างไรก็ตามฉันได้เห็นข้อความค้นหาที่ซับซ้อนมากที่มีตัวเชื่อมหลายตัวมีแผนแตกต่างกัน ล่าสุดที่ฉันเริ่มทำงานด้วยตารางที่มีจำนวนเกือบ 6 ล้านแถวเข้าร่วมกับตารางที่แตกต่างกันประมาณ 20 ตาราง เฉพาะการเข้าร่วมครั้งแรกในตารางนี้คือการเข้าร่วมภายในและอื่น ๆ ทั้งหมดถูกรวมไว้ด้านนอก ตัวกรองในส่วนคำสั่ง where ถูกทำพารามิเตอร์ดังนี้:

WHERE table1.begindate >= @startdate AND table1.enddate < @enddate 

ตัวกรองนี้ถูกใช้ในแผนภายหลังแทนก่อนหน้านี้ เมื่อฉันย้ายเงื่อนไขเหล่านี้ไปยังการเข้าร่วมภายในครั้งแรกแผนเปลี่ยนไปอย่างมากเนื่องจากตัวกรองถูกนำไปใช้ก่อนกำหนดในแผนเพื่อ จำกัด ชุดผลลัพธ์และ CPU ของฉันและเวลาที่ผ่านไปลดลงประมาณ 310% ดังนั้นเช่นเดียวกับคำถาม SQL Server จำนวนมากมันขึ้นอยู่กับ


2
คุณสามารถเพิ่มรายละเอียดเพิ่มเติม - อาจเป็นภาพหน้าจอของแผนผังแผนการปฏิบัติงาน - เนื่องจากคำตอบของคุณดูเหมือนจะขัดแย้งกับคนอื่นทั้งหมดหรือไม่?
Kenny Evitt

2
แผนแสดงการหมดเวลาของเครื่องมือเพิ่มประสิทธิภาพหรือไม่
Martin Smith เมื่อ

โหลด CPU อาจลดลงมากกว่า 100% ได้อย่างไร
Michael Green

2

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

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

มันง่ายกว่าเล็กน้อยสำหรับผู้พัฒนา SQL เป็นครั้งคราวในการมองเห็นตัวกรองในส่วนคำสั่ง WHERE แต่ฉันได้ทำงานกับตารางขนาดใหญ่บางส่วนที่มีตัวกรองในส่วนคำสั่ง ON ปิดเวลาทำงานนอกเวลาทำงาน

ดังนั้นหากส่วนคำสั่งมีศักยภาพที่จะลดจำนวนแถวที่แบบสอบถามจะอ่านได้อย่างมากฉันจะใส่ไว้ในส่วนคำสั่ง ON เพื่อช่วยให้เครื่องมือเพิ่มประสิทธิภาพเลือกแผนที่ดีกว่า


1

ภายใต้สถานการณ์ปกติคุณสามารถระบุเงื่อนไขตัวกรองได้ใน WHERE หรือ JOIN clause ฉันมักจะวางตัวกรองภายใต้ที่ใดยกเว้นว่าลำดับความสำคัญของการเข้าร่วมด้านนอกอาจได้รับผลกระทบ (ดูด้านล่าง) หรือหากตัวกรองนั้นเฉพาะเจาะจงมากกับตารางนั้น (เช่น TYPE = 12 เพื่อระบุชุดย่อยของแถวในตาราง)

ในทางกลับกันทั้งอนุประโยค ON และ WHERE สามารถใช้เพื่อระบุเงื่อนไขการเข้าร่วม (ตรงข้ามกับเงื่อนไขการกรอง) ตราบใดที่คุณใช้เพียงเข้าร่วมภายในก็ยังคงไม่สำคัญว่าคุณจะใช้ภายใต้สถานการณ์ปกติ

หากคุณใช้การรวม OUTER จะสามารถสร้างความแตกต่างได้อย่างมาก ตัวอย่างเช่นหากคุณระบุ OUTER JOIN ระหว่างสองตาราง (t1 และ t2) แต่จากนั้นใน WHERE clause ให้ไปเพื่อระบุความสัมพันธ์ eqijoin ระหว่างตาราง (เช่น t1.col = t2.col) คุณมีเพียง แปลง OUTER join เป็น INNER join! นี่เป็นเพราะ WHERE สามารถใช้เพื่อระบุ equijoin (หรืออาจรวม OUTER โดยขึ้นอยู่กับเวอร์ชันโดยใช้ * * = ไวยากรณ์ที่ไม่สนับสนุน) โดยไม่ต้องใช้คำสั่งย่อย ON และเมื่อ WHERE ระบุ Equijoin ภายในระหว่างตารางมันจะแทนที่ OUTER เข้าร่วม (ถ้ามี)

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


-1

ด้วย INNER JOIN มันเป็นปัญหาของสไตล์

อย่างไรก็ตามมันน่าสนใจยิ่งกว่าเมื่อเข้าร่วมนอก คุณควรสำรวจความแตกต่างระหว่างการค้นหาด้วยการเข้าร่วมด้านนอกและเงื่อนไขทั้งในส่วนคำสั่ง ON และส่วนคำสั่ง WHERE ชุดผลลัพธ์ไม่เหมือนกันเสมอไป ตัวอย่างเช่น

OUTER JOIN dbo.x ON a.ID = x.ID ... WHERE x.SomeField IS NOT NULL

เหมือนกับ

INNER JOIN dbo.x ON a.ID = x.ID AND x.SomeField IS NOT NULL

8
หากผลลัพธ์แตกต่างกัน (ซึ่งแน่นอน) อะไรคือจุดของการเปรียบเทียบประสิทธิภาพ
ypercubeᵀᴹ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.