Bagaimana saya bisa menyingkirkan cabang paralel yang tidak membantu ketika tidak memivot satu baris?

9

Pertimbangkan kueri berikut yang membatalkan beberapa agregat skalar:

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);

Pada SQL Server 2017, saya mendapatkan paket dengan dua cabang paralel. Cabang paralel kiri terasa tidak pada tempatnya. Pengoptimal memiliki jaminan bahwa hanya akan ada satu baris output dari agregat skalar global, namun operator induknya adalah Aliran Mendistribusikan dengan partisi round robin:

usul

Ketika saya menjalankan kueri, semua baris menuju ke utas tunggal seperti yang diharapkan. Tidak ada masalah kinerja dengan kueri ini, tetapi kueri cadangan 8 thread paralel dengan MAXDOP diatur ke 4. Sekali lagi, saya merasa bahwa ini tidak pada tempatnya. Mustahil bagi kedua cabang paralel untuk mengeksekusi pada saat yang sama. Saya ingin menghindari reservasi utas pekerja yang tidak perlu karena saya mengaktifkan TF 2467 yang mengubah algoritma penjadwalan untuk melihat jumlah utas pekerja per penjadwal.

Apakah mungkin untuk menulis ulang kueri agar memiliki persis satu cabang paralel yang berisi pemindaian tabel dan agregat lokal? Sebagai contoh, saya akan baik-baik saja dengan bentuk umum di bawah ini kecuali bahwa saya ingin loop bersarang dijalankan di zona serial:

masukkan deskripsi gambar di sini

Untuk Alasan Aplikasi ™, saya lebih suka menghindari membagi kueri ini menjadi beberapa bagian. Jika diinginkan, Anda dapat melihat paket permintaan aktual di sini . Jika Anda ingin bermain bersama di rumah, inilah T-SQL untuk membuat tabel yang digunakan dalam kueri:

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;
Joe Obbish
sumber

Jawaban:

8

Saya bisa mendapatkan bentuk rencana yang diinginkan dengan serial loop bergabung ketika semua hal berikut ini benar:

  • Sebuah APPLYatau CROSS JOINdigunakan sebagai gantiUNPIVOT
  • Tidak APPLYmengandung referensi luar
  • Sumber baris di APPLYadalah konstruktor nilai tabel yang bertentangan dengan tabel

Sebagai contoh, berikut adalah salah satu cara untuk melakukannya:

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);

Saya mendapatkan bentuk rencana rencana yang diinginkan seperti diklaim hanya dengan satu cabang paralel:

masukkan deskripsi gambar di sini

Saya mencoba banyak hal lain yang tidak berhasil. Jawaban ini tidak memuaskan karena saya tidak tahu mengapa ia bekerja dan mungkin tidak bekerja di versi SQL Server yang akan datang, tetapi itu memecahkan masalah saya.

Joe Obbish
sumber
8

Mustahil bagi kedua cabang paralel untuk mengeksekusi pada saat yang sama.

Eksekusi dimulai di tepi kiri rencana. Cabang loop bersarang sedang berjalan (membuka, menunggu data) saat cabang pemindaian tabel berjalan. Ini tidak bisa dihindari . Kedua cabang aktif pada saat yang sama, jadi SQL Server akan memesan 2 * pekerja DOP untuk paket ini.

Untuk solusi yang kuat, Anda bisa menempatkan pivot di fungsi bernilai tabel:

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;

Kemudian tulis ulang kueri sebagai:

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;

Fungsi menggunakan paralelisme dengan cabang tunggal yang diinginkan:

Rencana fungsi

Rencana eksekusi tingkat atas adalah:

Kueri tingkat atas

Paul White 9
sumber