Saya telah mendengar hal-hal yang bertentangan tentang hibah memori untuk kueri pemilihan paralel:
- Hibah memori dikalikan dengan DOP
- Hibah memori dibagi dengan DOP
Yang mana itu?
Saya telah mendengar hal-hal yang bertentangan tentang hibah memori untuk kueri pemilihan paralel:
Yang mana itu?
Jawaban:
Untuk permintaan SQL Server yang membutuhkan memori tambahan, hibah diturunkan untuk paket serial. Jika rencana paralel dieksplorasi dan dipilih, memori akan dibagi secara merata di antara utas.
Estimasi hibah memori didasarkan pada:
Jika rencana paralel dipilih, ada beberapa overhead memori untuk memproses pertukaran paralel (mendistribusikan, mendistribusikan, dan mengumpulkan stream), namun kebutuhan memori mereka masih belum dihitung dengan cara yang sama.
Operator yang paling umum yang meminta memori adalah
Operator yang kurang umum yang membutuhkan memori dimasukkan ke indeks penyimpanan kolom. Ini juga berbeda bahwa hibah memori saat ini dikalikan dengan DOP untuk mereka.
Kebutuhan memori untuk Macam biasanya jauh lebih tinggi daripada untuk hash. Urusan akan meminta setidaknya estimasi ukuran data untuk hibah memori, karena mereka perlu mengurutkan semua kolom hasil menurut elemen pemesanan. Hash membutuhkan memori untuk membangun tabel hash, yang tidak termasuk semua kolom yang dipilih.
Jika saya menjalankan kueri ini, dengan sengaja mengisyaratkan ke DOP 1, ia akan meminta memori 166 MB.
SELECT *
FROM
(
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
OPTION(MAXDOP 1);
Jika saya menjalankan kueri ini (sekali lagi, DOP 1), paket akan berubah, dan hibah memori akan naik sedikit.
SELECT *
FROM (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
JOIN (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u2
ON u.Id = u2.Id
OPTION(MAXDOP 1);
Ada dua Urusan, dan sekarang Hash Bergabung. Memori hibah naik sedikit untuk mengakomodasi hash build, tetapi tidak berlipat ganda karena operator Sortir tidak dapat berjalan secara bersamaan.
Jika saya mengubah kueri untuk memaksa loop bersarang bergabung, hibah akan berlipat ganda untuk berurusan dengan Urusan bersamaan.
SELECT *
FROM (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
INNER LOOP JOIN ( --Force the loop join
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u2
ON u.Id = u2.Id
OPTION(MAXDOP 1);
Memori hibah berlipat ganda karena Nested Loop bukan operator pemblokiran, dan Hash Join adalah.
Kueri ini memilih data string kombinasi yang berbeda. Bergantung pada kolom mana yang saya pilih, ukuran hibah memori akan naik.
Ukuran cara data dihitung untuk data string variabel adalah baris * 50% dari panjang kolom yang dinyatakan. Ini berlaku untuk VARCHAR dan NVARCHAR, meskipun kolom NVARCHAR digandakan karena mereka menyimpan karakter byte ganda. Ini memang berubah dalam beberapa kasus dengan CE baru, tetapi detailnya tidak didokumentasikan.
Ukuran data juga penting untuk operasi hash, tetapi tidak pada tingkat yang sama dengan yang dilakukannya untuk Macam.
SELECT *
FROM
(
SELECT TOP (1000)
u.Id -- 166MB (INT)
, u.DisplayName -- 300MB (NVARCHAR 40)
, u.WebsiteUrl -- 900MB (NVARCHAR 200)
, u.Location -- 1.2GB (NVARCHAR 100)
, u.AboutMe -- 9GB (NVARCHAR MAX)
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
OPTION(MAXDOP 1);
Jika saya menjalankan kueri ini di DOP yang berbeda, hibah memori tidak dikalikan dengan DOP.
SELECT *
FROM (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
INNER HASH JOIN (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u2
ON u.Id = u2.Id
ORDER BY u.Id, u2.Id -- Add an ORDER BY
OPTION(MAXDOP ?);
Ada sedikit peningkatan untuk menangani buffer paralel lebih banyak per operator pertukaran, dan mungkin ada alasan internal bahwa Sort dan Hash build membutuhkan memori ekstra untuk menangani DOP yang lebih tinggi, tetapi jelas bukan faktor pengali.