ฉันจะกำจัดสาขาคู่ขนานที่ไม่มีประโยชน์ได้อย่างไรเมื่อยกเลิกการตรึงแถวเดียว


9

ลองพิจารณาคำถามต่อไปนี้ที่ไม่ได้รวมจำนวนสเกลาร์จำนวนไม่กี่ตัว:

SELECT A, B
FROM (
    SELECT 
      MAX(CASE WHEN ID = 1 THEN 1 ELSE 0 END) VAL1
    , MAX(CASE WHEN ID = 2 THEN 1 ELSE 0 END) VAL2
    , MAX(CASE WHEN ID = 3 THEN 1 ELSE 0 END) VAL3
    , MAX(CASE WHEN ID = 4 THEN 1 ELSE 0 END) VAL4
    , MAX(CASE WHEN ID = 5 THEN 1 ELSE 0 END) VAL5
    , MAX(CASE WHEN ID = 6 THEN 1 ELSE 0 END) VAL6
    , MAX(CASE WHEN ID = 7 THEN 1 ELSE 0 END) VAL7
    , MAX(CASE WHEN ID = 16 THEN 1 ELSE 0 END) VAL16
    FROM dbo.PARALLEL_ZONE_REPRO
) q
UNPIVOT(B FOR A IN (
    VAL1
    ,VAL2
    ,VAL3
    ,VAL4
    ,VAL5
    ,VAL6
    ,VAL7
    ,VAL16
)) U
OPTION (MAXDOP 4);

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

โรบินกลม

เมื่อฉันเรียกใช้แบบสอบถามแถวทั้งหมดไปยังเธรดเดียวตามที่คาดไว้ ไม่มีปัญหาประสิทธิภาพการทำงานกับแบบสอบถามนี้ แต่แบบสอบถามสำรอง 8 กระทู้ขนานกับ MAXDOP ตั้งค่าเป็น 4 อีกครั้งฉันรู้สึกว่านี่เป็นสถานที่ มันเป็นไปไม่ได้ที่กิ่งก้านสาขาทั้งคู่จะดำเนินการในเวลาเดียวกัน ฉันต้องการหลีกเลี่ยงการจองเธรดผู้ปฏิบัติงานที่ไม่จำเป็นเนื่องจากฉันเปิดใช้งาน TF 2467 ซึ่งเปลี่ยนอัลกอริทึมการจัดตารางเวลาเพื่อดูจำนวนเธรดผู้ปฏิบัติงานต่อตัวกำหนดตารางเวลา

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

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

สำหรับ Application Reasons ™ฉันต้องการหลีกเลี่ยงการแยกแบบสอบถามนี้ออกเป็นส่วน ๆ หากต้องการคุณสามารถดูแผนแบบสอบถามที่เกิดขึ้นจริงที่นี่ หากคุณต้องการเล่นที่บ้านนี่คือ T-SQL เพื่อสร้างตารางที่ใช้ในการสืบค้น:

DROP TABLE IF EXISTS dbo.PARALLEL_ZONE_REPRO;

CREATE TABLE dbo.PARALLEL_ZONE_REPRO (
    ID BIGINT,
    FILLER VARCHAR(100)
);

INSERT INTO dbo.PARALLEL_ZONE_REPRO WITH (TABLOCK)
SELECT
  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) % 15
, REPLICATE('Z', 100)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

คำตอบ:


8

ฉันสามารถรับรูปร่างแผนที่ต้องการด้วยการเข้าร่วมลูปแบบอนุกรมเมื่อสิ่งต่อไปนี้เป็นจริง:

  • An APPLYหรือCROSS JOINถูกใช้แทนUNPIVOT
  • APPLYไม่มีการอ้างอิงด้านนอก
  • แหล่งที่มาของแถวในAPPLYนั้นเป็นตัวสร้างค่าของตารางซึ่งตรงข้ามกับตาราง

ตัวอย่างเช่นต่อไปนี้เป็นวิธีหนึ่งในการดำเนินการ:

SELECT A, B
FROM 
(
    SELECT A
    , MAX(
        CASE
            WHEN A = 'VAL1' THEN VAL1 
            WHEN A = 'VAL2' THEN VAL2
            WHEN A = 'VAL3' THEN VAL3
            WHEN A = 'VAL4' THEN VAL4
            WHEN A = 'VAL5' THEN VAL5
            WHEN A = 'VAL6' THEN VAL6
            WHEN A = 'VAL7' THEN VAL7
            WHEN A = 'VAL16' THEN VAL16
            ELSE NULL
        END
    ) B
    FROM (
         SELECT 
           MAX(CASE WHEN ID = 1 THEN 1 ELSE 0 END) VAL1
         , MAX(CASE WHEN ID = 2 THEN 1 ELSE 0 END) VAL2
         , MAX(CASE WHEN ID = 3 THEN 1 ELSE 0 END) VAL3
         , MAX(CASE WHEN ID = 4 THEN 1 ELSE 0 END) VAL4
         , MAX(CASE WHEN ID = 5 THEN 1 ELSE 0 END) VAL5
         , MAX(CASE WHEN ID = 6 THEN 1 ELSE 0 END) VAL6
         , MAX(CASE WHEN ID = 7 THEN 1 ELSE 0 END) VAL7
         , MAX(CASE WHEN ID = 16 THEN 1 ELSE 0 END) VAL16
         FROM dbo.PARALLEL_ZONE_REPRO
    ) q
    CROSS APPLY (
        VALUES ('VAL1'), ('VAL2'), ('VAL3'), ('VAL4'),
        ('VAL5'), ('VAL6'), ('VAL7'), ('VAL16') 
    ) ca (A)
    GROUP BY A
) q
WHERE q.B IS NOT NULL
OPTION (MAXDOP 4);

ฉันได้รับแผนรูปทรงที่ต้องการตามที่อ้างว่ามีเพียงสาขาเดียว:

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

ฉันลองสิ่งอื่น ๆ อีกมากมายที่ไม่ทำงาน คำตอบนี้ไม่น่าพอใจที่ฉันไม่รู้ว่าทำไมมันทำงานได้และมันอาจไม่ทำงานใน SQL Server รุ่นอนาคต แต่ก็แก้ปัญหาของฉันได้


8

มันเป็นไปไม่ได้ที่กิ่งก้านสาขาทั้งคู่จะดำเนินการในเวลาเดียวกัน

การดำเนินการเริ่มต้นที่ขอบด้านซ้ายของแผน กิ่งย่อยของลูปซ้อนกำลังทำงานอยู่ (กำลังเปิดอยู่กำลังรอข้อมูล) เมื่อสาขาสแกนตารางกำลังทำงาน นี่คือหลีกเลี่ยงไม่ได้ สาขาทั้งสองมีการใช้งานพร้อมกันดังนั้น SQL Server จะสำรองพนักงาน DOP 2 * สำหรับแผนนี้

สำหรับโซลูชันที่มีประสิทธิภาพคุณสามารถวางเดือยในฟังก์ชันที่ให้คุณค่ากับตาราง:

CREATE OR ALTER FUNCTION dbo.PivotPZR()
RETURNS @R table 
(
    VAL1 bigint NOT NULL, VAL2 bigint NOT NULL,
    VAL3 bigint NOT NULL, VAL4 bigint NOT NULL,
    VAL5 bigint NOT NULL, VAL6 bigint NOT NULL,
    VAL7 bigint NOT NULL, VAL16 bigint NOT NULL
)
WITH SCHEMABINDING AS
BEGIN
    DECLARE 
        @Val1 bigint, @Val2 bigint, @Val3 bigint, @Val4 bigint,
        @Val5 bigint, @Val6 bigint, @Val7 bigint, @Val16 bigint;

    -- Can use parallelism
    SELECT
        @Val1 = MAX(CASE WHEN PZR.ID = 1 THEN 1 ELSE 0 END),
        @Val2 = MAX(CASE WHEN PZR.ID = 2 THEN 1 ELSE 0 END),
        @Val3 = MAX(CASE WHEN PZR.ID = 3 THEN 1 ELSE 0 END),
        @Val4 = MAX(CASE WHEN PZR.ID = 4 THEN 1 ELSE 0 END),
        @Val5 = MAX(CASE WHEN PZR.ID = 5 THEN 1 ELSE 0 END),
        @Val6 = MAX(CASE WHEN PZR.ID = 6 THEN 1 ELSE 0 END),
        @Val7 = MAX(CASE WHEN PZR.ID = 7 THEN 1 ELSE 0 END),
        @Val16 = MAX(CASE WHEN PZR.ID = 16 THEN 1 ELSE 0 END)
    FROM dbo.PARALLEL_ZONE_REPRO AS PZR;

    -- Single result row
    INSERT @R
        (VAL1, VAL2, VAL3, VAL4, VAL5, VAL6, VAL7, VAL16)
    VALUES
        (@Val1, @Val2, @Val3, @Val4, @Val5, @Val6, @Val7, @Val16);

    RETURN;
END;

จากนั้นเขียนแบบสอบถามใหม่เป็น:

SELECT
    U.A,
    U.B
FROM dbo.PivotPZR() AS PP
UNPIVOT
(
    B FOR A IN (VAL1, VAL2 ,VAL3 ,VAL4, VAL5 ,VAL6 ,VAL7 ,VAL16)
) AS U;

ฟังก์ชั่นนี้ใช้การขนานกับสาขาเดียวตามที่ต้องการ:

แผนฟังก์ชั่น

แผนการดำเนินการระดับบนสุดคือ:

แบบสอบถามระดับสูงสุด

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