SQL Server 2008 Hosting :: Parameter Sniffing Resolution

Pada artikel saya kali ini saya akan berbicara tentang cara-cara untuk menyelesaikan Parameter Sniffing pada SQL Server 2008. Metode untuk menyelesaikan masalah Parameter Sniffing tercantum di bawah ini:

  1. Menggunakan local variable dengan prosedur.
  2. Menggunakan recompile option saat create prosedur.
  3. Menggunakan Query OPTIME FOR.

Mari kita telusuri satu per satu.

Menggunakan Local Variable dengan Prosedur.

DROP TABLE fruit
GO
CREATE TABLE fruit (Sno int identity,frtname varchar(20),frttype int)
GO
— Insert dummy data
INSERT INTO fruit Values(‘Apple’,rand()*1000)
GO 10000
INSERT INTO fruit Values(‘Mango’,rand()*1000)
GO 10
CREATE unique clustered index ix_sno on fruit(sno)
GO
CREATE INDEX ix_frtname on fruit(frtname) include(frttype)
GO

Script di atas adalah script yang mengisi TABLE FRUIT dengan nilai-nilai(value).

CREATE Proc usp_fetchfruits
@frtname varchar(20)
AS
BEGIN
SELECT * FROM fruit WHERE frtname=@frtname
END
GO
— procedure with local variables
CREATE Proc usp_fetchfruits_localvar
@frtname varchar(20)
AS
BEGIN
DECLARE @fruitname varchar(20)
SET @fruitname=@frtname
SELECT * FROM fruit WHERE frtname=@fruitname
END
GO

Query di atas mengcreate dua prosedur usp_fetchfruits dan usp_fetchfruits_localvar. Prosedur usp_fetchfruits_localvar menggunakan local variable.. Sekarang Mari kita bandingkan rencana pelaksanaan prosedur di atas.

1Snapshot diatas membandingkan rencana eksekusi dari dua prosedur. Perbedaan jumlah optimizer estimasi dan actual number pada baris kedua karena optimizer tidak tahu nilai parameter sebenarnya harus dilewatkan kemana, sehingga optimizer menciptakan rencana generik berdasarkan statistik yang tersedia. Table fruit memiliki total 10010 baris dan jumlah optimizer estimasi baris adalah 5005 yang persis setengah dari jumlah total.

Metode ini tidak menyelesaikan masalah performa tapi mungkin tidak begitu efektif jika jumlah baris sebenarnya adalah cara yang lebih besar daripada rata-rata baris yang diperkirakan.

Menggunakan Recompile Option saat membuat prosedur.
masalah Parameter Sniffing terjadi karena rencana cache dari eksekusi pertama digunakan dalam future procedure execution(eksekusi prosedur yang akan dating). Jika prosedur ini sedang disusun dan rencana disiapkan lagi untuk setiap eksekusi dari Parameter Sniffing maka akan diselesaikan. Inilah yang disebut dengan Recompile ketika digunakan dalam definisi prosedur. Recompile prosedur ini untuk membuat rencana baru setiap kali prosedur dijalankan.

CREATE Proc usp_fetchfruits_withrecompile
@frtname varchar(20)
WITH RECOMPILE
AS
BEGIN
SELECT * FROM fruit WHERE frtname=@frtname
END

2Snapshot diatas, baik dalam eksekusi rencana optimizer yang estimasi maupun catatan actual number yang sama karena rencana yang telah di recompile untuk setiap nilai parameter bukan rencana cache yang digunakan pada eksekusi kedua.

Masalah dengan metode ini adalah bahwa resource digunakan untuk recompile prosedur setiap kalinya. Rencana ini bahkan merecompile untuk nilai-nilai parameter yang mungkin mendapat manfaat dari rencana cache.

Query OPTIMIZE FOR
Dengan menggunakan query OPTIMIZE FOR kita dapat memiliki sebuah query SQL Server optimize berdasarkan nilai parameter tertentu.

CREATE Proc usp_fetchfruits_optimizefor
@frtname varchar(20)
AS
BEGIN
SELECT * FROM fruit WHERE frtname=@frtname
OPTION (OPTIMIZE FOR (@frtname = ‘Mango’))
END

Pada prosedur di atas, tidak memperdulikan nilai parameter yang mensupply select query yang akan dioptimalkan pada nilai “Mango”.

3Snapshot diatas membandingkan rencana eksekusi untuk nilai parameter “Apple” dan “Mango”. Dalam kedua rencana tersebut nilai-nilai estimasi tetap 10000 yang merupakan jumlah total untuk parameter “Apple”.

SQL Server 2008 memperluas query OPTIMIZE FOR sehingga dapat mengoptimalkan query untuk nilai yang tidak diketahui. Ini agak mirip dengan metode menggunakan variabel lokal.

CREATE Proc usp_fetchfruits_optimizeforunknown
@frtname varchar(20)
AS
BEGIN
SELECT * FROM fruit WHERE frtname=@frtname
OPTION (OPTIMIZE FOR UNKNOWN)
END

Prosedur di atas menggunakan query OPTIMIZE FOR UNKNOWN untuk menyingkirkan masalah parameter sniffing.

4Snapshot diatas membandingkan eksekusi untuk nilai parameter Apple dan Mango. Optimizer memperkirakan jumlah rata-rata baris yang dikembalikan seperti ketika menggunakan variabel lokal.

Cara lain adalah dengan membuat prosedur yang tersimpan ganda dan memanggil mereka didasarkan pada nilai parameter. Misalnya, Dalam hal ini kita dapat membuat 2 prosedur yang berbeda satu untuk parameter nilai mangga dan satu untuk nilai parameter Apple dan memanggil mereka berdasarkan nilai parameter yang disediakan.

Kesimpulan
Pada artikel ini saya berbicara tentang cara-cara untuk meningkatkan kinerja pada saat menghadapi masalah PARAMETER SNIFFING.