ไวยากรณ์ของ INNER JOIN ซ้อนอยู่ภายใน OUTER JOIN เปรียบเทียบกับผลการสืบค้น


10

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

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

SELECT  a.*, m.*, n.*
FROM    dbo.Autos a
LEFT JOIN dbo.Models m
  JOIN dbo.Manufacturers n  -- <-- Nested INNER JOIN
  ON n.ManufacturerID = m.ManufacturerID
ON m.ModelID = a.ModelID

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

สิ่งนี้ไม่จำเป็นต้องทำให้ผู้ผลิตเข้าร่วมเพื่อรวมแถว auto กับ ModelID ที่ไม่ได้อยู่ในตาราง Models

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

การใช้ไวยากรณ์แบบดั้งเดิมเราต้องเปลี่ยนการเข้าร่วมเป็นผู้ผลิตเป็นการรวมภายนอกเช่น ... แต่สิ่งนี้เปลี่ยนแผนแบบสอบถาม

SELECT a.*, m.*, n.*
FROM dbo.Autos a
LEFT JOIN dbo.Models m
ON m.ModelID = a.ModelID
LEFT JOIN dbo.Manufacturers n -- <-- Now LEFT OUTER JOIN
ON n.ManufacturerID = m.ManufacturerID

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

คำตอบ:


12

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

แผนสองมีค่าใช้จ่ายที่ต่ำกว่าโดยประมาณดังนั้นในแง่ที่ จำกัด จึงเป็น 'ดีกว่า'

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

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

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

ฉันได้ตระหนักว่าไวยากรณ์ที่ซ้อนกันยังปรับเปลี่ยนพฤติกรรมของแบบสอบถาม

'ไวยากรณ์ที่ซ้อนกัน' เป็นเพียงแง่มุมหนึ่งของข้อกำหนดคุณลักษณะการรวมไวยากรณ์ ANSI ทั้งหมด ในการเปิดใช้งานข้อมูลจำเพาะเชิงตรรกะเต็มรูปแบบสำหรับรูปแบบการรวมที่ซับซ้อนยิ่งขึ้นข้อมูลจำเพาะอนุญาตให้ใช้วงเล็บ (ไม่จำเป็น) และFROMคำสั่งย่อยย่อย

แบบสอบถามสามารถเขียนได้โดยใช้ไวยากรณ์ ANSI เดียวกันโดยใช้วงเล็บ:

SELECT
    A.*,
    M.*,
    N.* 
FROM dbo.Autos AS A
LEFT JOIN
(
    dbo.Manufacturers AS N
    JOIN dbo.Models AS M
        ON M.ManufacturerID = N.ManufacturerID
) ON M.ModelID = A.ModelID;

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

SELECT
    A.*,
    M.*,
    N.* 
FROM dbo.Autos AS A
LEFT JOIN dbo.Manufacturers AS N
JOIN dbo.Models AS M
    ON M.ManufacturerID = N.ManufacturerID
    ON M.ModelID = A.ModelID;

นี่ไม่ใช่ไวยากรณ์ที่แตกต่าง - เป็นเพียงการละเว้นวงเล็บทางเลือกและฟอร์แมตใหม่

ดังที่มาร์ตินกล่าวถึงเป็นไปได้ในกรณีนี้ที่จะแสดงความต้องการทางตรรกะโดยใช้การรวมภายในแล้วตามด้วยการรวมภายนอกด้านขวา:

SELECT
    A.*,
    M.*,
    N.* 
FROM dbo.Manufacturers AS N
JOIN dbo.Models AS M
    ON M.ManufacturerID = N.ManufacturerID
RIGHT JOIN dbo.Autos AS A
    ON A.ModelID = M.ModelID;

แบบฟอร์มแบบสอบถามทั้งสามแบบด้านบนใช้ไวยากรณ์การเข้าร่วม ANSI เดียวกัน ทั้งสามเกิดขึ้นเพื่อสร้างแผนการดำเนินการทางกายภาพเดียวกันกับชุดข้อมูลที่ให้ไว้:

แผนการดำเนินการทั่วไป

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

มาตรฐาน SQL ยังอนุญาตให้FROMใช้เคียวรีย่อย clause ได้อีกวิธีหนึ่งในการเขียนข้อกำหนดเคียวรีเดียวกันคือ:

SELECT * 
FROM dbo.Autos AS A
LEFT JOIN
(
    SELECT
        N.ManufacturerID,
        ManufacturerName = N.Name,
        M.ModelID,
        ModelName = M.Name
    FROM dbo.Manufacturers AS N
    JOIN dbo.Models AS M
        ON M.ManufacturerID = N.ManufacturerID
) AS R1
    ON R1.ModelID = A.ModelID;

การใช้ไวยากรณ์ดั้งเดิมเราต้องเปลี่ยนการเข้าร่วมเป็น `ผู้ผลิตเป็นการรวมภายนอกเช่นนั้น ... แต่สิ่งนี้จะเปลี่ยนแผนแบบสอบถาม

นี้น่าจะมีการเปลี่ยนแปลงความหมายของแบบสอบถามในกรณีที่มันเป็นเทคนิคที่ไม่เป็นทางเลือกที่ถูกต้อง ( แต่เห็นypercube 's ความคิดเห็นในคำถามของคุณ)

เครื่องหมายวงเล็บ (เป็นทางเลือก) ในไวยากรณ์การเข้าร่วม ANSI นั้นมีความแม่นยำมากขึ้นสำหรับข้อกำหนดการเข้าร่วมที่ซับซ้อนเช่นนี้ดังนั้นคุณไม่ควรกลัวที่จะใช้มันเมื่อจำเป็น

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