kueri peningkatan kinerja dengan menghapus gabung internal hash match

9

Ketika mencoba menerapkan isi pertanyaan ini di bawah ini untuk situasi saya sendiri, saya agak bingung bagaimana saya bisa menyingkirkan operator Hash Match (Inner Join) jika ada cara yang memungkinkan.

Kinerja kueri SQL Server - menghapus kebutuhan untuk Hash Match (Inner Join)

Saya perhatikan biaya 10% dan bertanya-tanya apakah saya bisa menguranginya. Lihat paket kueri di bawah ini.

masukkan deskripsi gambar di sini

Karya ini berasal dari kueri yang harus saya sesuaikan hari ini:

SELECT c.AccountCode, MIN(d.CustomerSID) 
FROM   Stage.Customer c 
INNER JOIN Dimensions.Customer d  ON c.Email = d.Email
                                  OR (
                                          c.HomePostCode = d.HomePostCode
                                       AND c.StrSurname = d.strSurname
                                                                    )
GROUP BY c.AccountCode

dan setelah menambahkan indeks ini:

---------------------------------------------------------------------
-- Create the indexes
---------------------------------------------------------------------

CREATE NONCLUSTERED INDEX IDX_Stage_Customer_HOME_SURNAME_INCL
ON Stage.Customer(HomePostCode ,strSurname)
INCLUDE (AccountCode)
--WHERE HASEMAIL = 0
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go


CREATE NONCLUSTERED INDEX IDX_Dimensions_Customer_HOME_SURNAME_INCL
ON Dimensions.Customer(HomePostCode ,strSurname)
INCLUDE (AccountCode,CustomerSID)
--WHERE HASEMAIL = 0
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go



CREATE NONCLUSTERED INDEX IDX_Stage_Customer_EMAIL_INCL
ON Stage.Customer(EMAIL)
INCLUDE (AccountCode)
--WHERE HASEMAIL = 1
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go


CREATE NONCLUSTERED INDEX IDX_Dimensions_Customer_EMAIL_INCL
ON Dimensions.Customer(EMAIL)
INCLUDE (AccountCode,CustomerSID)
--WHERE HASEMAIL = 1
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go

ini permintaan baru:

----------------------------------------------------------------------------
-- new query 
----------------------------------------------------------------------------

SELECT * 
FROM (    
SELECT AccountCode
     ,RO=ROW_NUMBER () OVER (PARTITION BY AccountCode ORDER BY CustomerSID)
     --,CustomerSID=MIN(CustomerSID) OVER (PARTITION BY AccountCode ORDER BY AccountCode)
       ,CustomerSID
FROM (    
          SELECT c.AccountCode, D.CustomerSID
       FROM   Stage.Customer c 
       INNER JOIN Dimensions.Customer d  ON c.Email = d.Email

          UNION ALL

          SELECT c.AccountCode, D.CustomerSID
       FROM   Stage.Customer c 
       INNER JOIN Dimensions.Customer d  ON c.HomePostCode = d.HomePostCode
                                        AND c.StrSurname = d.strSurname
) RADHE
) R1
WHERE RO = 1

Ini telah mengurangi waktu eksekusi permintaan dari 8 menit menjadi 1 detik.

Semua orang senang, tetapi saya masih ingin tahu apakah saya bisa menyelesaikan lebih banyak, yaitu dengan cara menghapus operator hash match.

Mengapa ada di sana pada awalnya, saya mencocokkan semua bidang, mengapa hash?

Marcello Miorelli
sumber

Jawaban:

14

tautan berikut ini akan memberikan sumber pengetahuan yang bagus tentang rencana eksekusi.

Dari Dasar-dasar Rencana Eksekusi - Kebingungan Pertandingan Hash yang saya temukan:

Dari http://sqlinthewild.co.za/index.php/2007/12/30/execution-plan-operations-joins/

"Gabung hash adalah salah satu operasi gabung yang lebih mahal, karena membutuhkan pembuatan tabel hash untuk melakukan gabung. Yang mengatakan, gabung yang terbaik untuk input besar, tidak disortir. Ini adalah yang paling intensif memori dari semua dari gabungan

Bergabung dengan hash pertama membaca salah satu input dan hash kolom bergabung dan menempatkan nilai hash dan kolom yang dihasilkan ke dalam tabel hash dibangun di memori. Kemudian ia membaca semua baris di input kedua, hash itu dan memeriksa baris di ember hash yang dihasilkan untuk baris bergabung. "

yang menaut ke pos ini:

http://blogs.msdn.com/b/craigfr/archive/2006/08/10/687630.aspx

Bisakah Anda menjelaskan rencana eksekusi ini? memberikan wawasan yang baik tentang rencana eksekusi dengan, tidak khusus untuk hash match tetapi relevan.

Pemindaian konstan adalah cara untuk SQL Server untuk membuat ember di mana itu akan menempatkan sesuatu nanti dalam rencana eksekusi. Saya telah memposting penjelasan yang lebih menyeluruh di sini . Untuk memahami untuk apa pemindaian konstan, Anda harus melihat lebih jauh ke dalam rencana. Dalam hal ini, operator Compute Scalar yang digunakan untuk mengisi ruang yang dibuat oleh pemindaian konstan.

Operator Compute Scalar sedang dimuat dengan NULL dan nilai 1045876, jadi mereka jelas akan digunakan dengan Loop Join dalam upaya untuk memfilter data.

Bagian yang sangat keren adalah bahwa rencana ini adalah Sepele. Itu berarti bahwa ia melewati proses optimasi minimal. Semua operasi mengarah ke Interval Penggabungan. Ini digunakan untuk membuat satu set minimal operator perbandingan untuk pencarian indeks ( detailnya di sini ).

Dalam pertanyaan ini: Bisakah saya meminta SSMS untuk menunjukkan kepada saya biaya permintaan aktual di panel rencana eksekusi? Saya memperbaiki masalah kinerja pada prosedur tersimpan multistatement di SQL Server. Saya ingin tahu bagian mana yang harus saya habiskan.

Saya mengerti dari Bagaimana saya membaca Biaya Permintaan, dan apakah selalu berupa persentase? bahwa bahkan ketika SSMS diberitahu untuk menyertakan Rencana Eksekusi Aktual, angka "Biaya kueri (relatif terhadap bets)" masih didasarkan pada perkiraan biaya, yang mungkin jauh dari aktual

Mengukur Kinerja Kueri: "Biaya Permintaan Rencana Eksekusi" vs "Waktu Diambil" memberikan informasi yang baik ketika Anda perlu membandingkan kinerja 2 kueri yang berbeda.

Dalam membaca paket eksekusi SQL Server Anda dapat menemukan tips hebat untuk membaca rencana eksekusi.

Pertanyaan / jawaban lain yang sangat saya sukai karena relevan dengan subjek ini, dan untuk referensi pribadi saya ingin mengutip adalah:

Cara mengoptimalkan kueri T-SQL menggunakan Rencana Eksekusi

dapat sql menghasilkan rencana yang bagus untuk prosedur ini?

Paket Eksekusi Berbeda untuk Pernyataan SQL yang Sama

Marcello Miorelli
sumber