การใช้ DISTINCT เป็นคำใบ้ในแบบสอบถามย่อยมีประโยชน์หรือไม่


18

การเพิ่มDISTINCTในตัวอย่างต่อไปนี้มีผลกระทบต่อเวลาทำงานของแบบสอบถามหรือไม่
ควรใช้เป็นคำใบ้ในบางครั้งหรือไม่?

SELECT *
FROM   A
WHERE  A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B) 

คำตอบ:


25

เมื่อสงสัยเกี่ยวกับสิ่งต่าง ๆ เช่นนี้คุณควรเปรียบเทียบแผนการดำเนินการกับข้อความค้นหาของคุณ

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

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

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

แผนปฏิบัติการสำหรับสองกรณีที่ชัดเจนในการทดสอบอีกแถวใน B มากกว่า A และจำนวนแถวเท่ากันในตารางยังแสดงแผนการดำเนินการเดียวกันสำหรับแบบสอบถาม

ปรับปรุง

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

ทรีอินพุทสำหรับเคียวรีนั้นแตกต่างกันอย่างชัดเจน แต่หลังจากการทำให้เข้าใจง่ายพวกมันก็เหมือนกัน

Ref: เครื่องมือเพิ่มประสิทธิภาพแบบสอบถามที่ไม่มีเอกสารเพิ่มเติมติดตามค่าสถานะและเครื่องมือเพิ่มประสิทธิภาพการสืบค้น Deep Dive - ส่วนที่ 2

ต้นไม้ที่ป้อนและต้นไม้ที่ง่ายสำหรับการสืบค้นโดยใช้ที่แตกต่างกัน:

*** Input Tree: ***
        LogOp_Project QCOL: [xx].[dbo].[A].SomeColumn
            LogOp_Select
                LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002 
                ScaOp_SomeComp 2
                    ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
                    LogOp_GbAgg OUT(QCOL: [xx].[dbo].[B].SomeColumn,) BY(QCOL: [xx].[dbo].[B].SomeColumn,)
                        LogOp_Project
                            LogOp_Project
                                LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006 
                                AncOp_PrjList 
                            AncOp_PrjList 
                        AncOp_PrjList 
            AncOp_PrjList 
*******************
*** Simplified Tree: ***
        LogOp_LeftSemiJoin
            LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002 
            LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006 
            ScaOp_Comp x_cmpEq
                ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
                ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
*******************

ต้นไม้การป้อนข้อมูลและต้นไม้ที่เรียบง่ายสำหรับการสืบค้นที่ไม่ได้ใช้ที่แตกต่างกัน:

*** Input Tree: ***
        LogOp_Project QCOL: [xx].[dbo].[A].SomeColumn
            LogOp_Select
                LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002 
                ScaOp_SomeComp 2
                    ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
                    LogOp_Project
                        LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006 
                        AncOp_PrjList 
            AncOp_PrjList 
*******************
*** Simplified Tree: ***
        LogOp_LeftSemiJoin
            LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002 
            LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006 
            ScaOp_Comp x_cmpEq
                ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
                ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
*******************
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.