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