Mengapa saya TIDAK menggunakan opsi SQL Server "optimalkan untuk beban kerja ad hoc"?

49

Saya telah membaca beberapa artikel hebat tentang caching paket SQL Server oleh Kimberly Tripp seperti ini: http://www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/

Mengapa ada opsi untuk "mengoptimalkan beban kerja ad hoc"? Bukankah seharusnya ini selalu menyala? Apakah pengembang menggunakan ad-hoc SQL atau tidak, mengapa Anda tidak mengaktifkan opsi ini pada setiap contoh yang mendukungnya (SQL 2008+), sehingga mengurangi cache bloat?

Beberapa pria
sumber

Jawaban:

45

Tim pengembangan SQL Server bekerja berdasarkan prinsip paling tidak mengejutkan - sehingga SQL Server umumnya memiliki fitur baru yang dinonaktifkan untuk mempertahankan perilaku seperti versi sebelumnya.

Ya, optimalkan untuk beban kerja adhoc sangat bagus untuk mengurangi mengasapi cache rencana - tetapi selalu mengujinya terlebih dahulu!

[Sunting: Kalen Delaney memberi tahu anekdot yang menarik bahwa ia bertanya kepada salah satu teman insinyur Microsoftnya apakah akan ada keadaan di mana tidak pantas untuk mengaktifkan ini. Dia kembali beberapa hari kemudian untuk mengatakan - bayangkan aplikasi yang memiliki BANYAK pertanyaan yang berbeda, dan setiap kueri berjalan persis dua kali total. Maka itu mungkin tidak pantas. Cukuplah untuk mengatakan tidak ada banyak aplikasi seperti itu!]

[Sunting: Jika sebagian besar pertanyaan Anda dieksekusi lebih dari satu kali (tidak persis dua kali); itu mungkin tidak pantas. Aturan umum adalah untuk mengubahnya jika ada banyak permintaan adhoc sekali pakai pada database; namun, masih belum banyak aplikasi seperti itu.]

Peter Schofield
sumber
9
+1 fitur baru sangat, sangat jarang dihidupkan secara default. Saya benar-benar tidak dapat memikirkan alasan bagus untuk tidak mengaktifkan fitur khusus ini - paling buruk semua pertanyaan Anda adalah sekali pakai dan tidak akan mendapat manfaat dari caching.
Aaron Bertrand
1
Ini adalah jawaban "aman" berdasarkan akal sehat dan tidak menjawab pertanyaan. Penanya ingin mengetahui secara khusus kasus penggunaan ketika TIDAK mengaktifkan fitur ini lebih baik.
MikeTeeVee
2
MikeTeeVee - itu mungkin jawaban yang aman, tetapi ini adalah salah satu fitur di mana saya benar-benar tidak bisa memikirkan alasan untuk tidak mengaktifkannya. Karena sangat mengagumkan, saya hanya ingin menjelaskan mengapa itu mati secara default!
Peter Schofield
21

Di bawah ini adalah kode kecil yang akan membantu Anda memutuskan apakah "beralih mengoptimalkan untuk beban kerja ad hoc ON / OFF" akan bermanfaat atau tidak. Kami biasanya memeriksa ini sebagai bagian dari pemeriksaan kesehatan kami untuk server internal dan klien.

Ini adalah opsi teraman untuk diaktifkan dan dijelaskan dengan baik oleh Brad di sini dan oleh Glenn Berry di sini .

--- for 2008 and up .. Optimize ad-hoc for workload 
IF EXISTS (
        -- this is for 2008 and up
        SELECT 1
        FROM sys.configurations
        WHERE NAME = 'optimize for ad hoc workloads'
        )
BEGIN
    DECLARE @AdHocSizeInMB DECIMAL(14, 2)
        ,@TotalSizeInMB DECIMAL(14, 2)
        ,@ObjType NVARCHAR(34)

    SELECT @AdHocSizeInMB = SUM(CAST((
                    CASE 
                        WHEN usecounts = 1
                            AND LOWER(objtype) = 'adhoc'
                            THEN size_in_bytes
                        ELSE 0
                        END
                    ) AS DECIMAL(14, 2))) / 1048576
        ,@TotalSizeInMB = SUM(CAST(size_in_bytes AS DECIMAL(14, 2))) / 1048576
    FROM sys.dm_exec_cached_plans

    SELECT 'SQL Server Configuration' AS GROUP_TYPE
        ,' Total cache plan size (MB): ' + cast(@TotalSizeInMB AS VARCHAR(max)) + '. Current memory occupied by adhoc plans only used once (MB):' + cast(@AdHocSizeInMB AS VARCHAR(max)) + '.  Percentage of total cache plan occupied by adhoc plans only used once :' + cast(CAST((@AdHocSizeInMB / @TotalSizeInMB) * 100 AS DECIMAL(14, 2)) AS VARCHAR(max)) + '%' + ' ' AS COMMENTS
        ,' ' + CASE 
            WHEN @AdHocSizeInMB > 200
                OR ((@AdHocSizeInMB / @TotalSizeInMB) * 100) > 25 -- 200MB or > 25%
                THEN 'Switch on Optimize for ad hoc workloads as it will make a significant difference. Ref: http://sqlserverperformance.idera.com/memory/optimize-ad-hoc-workloads-option-sql-server-2008/. http://www.sqlskills.com/blogs/kimberly/post/procedure-cache-and-optimizing-for-adhoc-workloads.aspx'
            ELSE 'Setting Optimize for ad hoc workloads will make little difference !!'
            END + ' ' AS RECOMMENDATIONS
END
Kin Shah
sumber
7

Pikirkan server produksi yang hanya melayani 5 kueri yang berbeda, tetapi beberapa ribu dari itu per detik. Anda adalah tim pengembangan Microsoft SQL Server. Anda akan mengutak-atik caching rencana. Apakah Anda mengaktifkan perilaku ini secara default, ketika Anda tahu bahwa beberapa klien Anda yang terbesar dan paling kritis (misalnya, implementasi SAP internal Microsoft) bekerja di kampus yang sama dan menggunakan kafetaria yang sama seperti yang Anda lakukan?

Stu
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Paul White
7

Ketika Anda mengaktifkan opsi " Optimalkan untuk Beban Kerja Ad Hoc ", Anda akan menyebabkan permintaan ad-hoc yang dijalankan pada kali ke-2 menjadi sama lambatnya dengan tanggal 1, karena Anda akan Menyusun Rencana Eksekusi dan menarik data yang sama ( tanpa itu di-cache) itu 2 kali pertama.
Ini mungkin bukan masalah besar, tetapi Anda akan menyadarinya saat menguji kueri.
Jadi apa yang terjadi sekarang, tanpa opsi ini dihidupkan dan cache penuh dengan permintaan Ad-Hoc 1-Off?

Algoritma Manajemen Caching:

Ketika fitur Optimasi ini diperkenalkan, algoritma manajemen caching juga diperbarui.
Artikel Kimberly Tripp juga merujuk pada posting Kalen Delaney tentang perubahan algoritma ini.
Dia menjelaskan yang terbaik:

Perubahan sebenarnya menghitung ukuran cache rencana di mana SQL Server mengakui bahwa ada tekanan memori, dan itu akan mulai menghapus paket dari cache. Paket yang akan dihapus adalah paket murah yang belum digunakan kembali, dan ini adalah HAL YANG BAIK.

Ini berarti rencana satu kali sial itu akan menjadi yang pertama ketika Anda perlu membebaskan sumber daya.

Jadi sekarang pertanyaannya menjadi:

    " Mengapa kita MEMBUTUHKAN 'Optimalkan untuk Beban Kerja Ad Hoc' ketika SQL Server menangani menghapus paket yang tidak digunakan bila perlu? "

Jawaban saya adalah, jika Anda secara teratur memiliki s-ton oodles dinamis-sql yang menghasilkan iklan tanpa parameter permintaan -hoc, maka masuk akal untuk mengaktifkan fitur ini.
Anda ingin menghindari menempatkan beban pada sumber daya sistem, sehingga memaksa rencana cache / penghapusan data setelah Anda menggunakan ruang memori cache maksimal.

Bagaimana saya tahu kapan saya harus menyalakan ini?

Berikut adalah kueri yang saya tulis untuk menunjukkan kepada Anda berapa banyak Rencana Ad-Hoc yang saat ini Anda cached dan berapa banyak ruang disk yang mereka makan (hasilnya akan berubah sepanjang hari - jadi ujilah selama waktu beban berat):

--Great query for making the argument to use "Optimize for Ad Hoc Workloads":
SELECT S.CacheType, S.Avg_Use, S.Avg_Multi_Use,
       S.Total_Plan_3orMore_Use, S.Total_Plan_2_Use, S.Total_Plan_1_Use, S.Total_Plan,
       CAST( (S.Total_Plan_1_Use * 1.0 / S.Total_Plan) as Decimal(18,2) )[Pct_Plan_1_Use],
       S.Total_MB_1_Use,   S.Total_MB,
       CAST( (S.Total_MB_1_Use   * 1.0 / S.Total_MB  ) as Decimal(18,2) )[Pct_MB_1_Use]
  FROM
  (
    SELECT CP.objtype[CacheType],
           COUNT(*)[Total_Plan],
           SUM(CASE WHEN CP.usecounts > 2 THEN 1 ELSE 0 END)[Total_Plan_3orMore_Use],
           SUM(CASE WHEN CP.usecounts = 2 THEN 1 ELSE 0 END)[Total_Plan_2_Use],
           SUM(CASE WHEN CP.usecounts = 1 THEN 1 ELSE 0 END)[Total_Plan_1_Use],
           CAST((SUM(CP.size_in_bytes * 1.0) / 1024 / 1024) as Decimal(12,2) )[Total_MB],
           CAST((SUM(CASE WHEN CP.usecounts = 1 THEN (CP.size_in_bytes * 1.0) ELSE 0 END)
                      / 1024 / 1024) as Decimal(18,2) )[Total_MB_1_Use],
           CAST(AVG(CP.usecounts * 1.0) as Decimal(12,2))[Avg_Use],
           CAST(AVG(CASE WHEN CP.usecounts > 1 THEN (CP.usecounts * 1.0)
                         ELSE NULL END) as Decimal(12,2))[Avg_Multi_Use]
      FROM sys.dm_exec_cached_plans as CP
     GROUP BY CP.objtype
  ) AS S
 ORDER BY S.CacheType

Hasil: masukkan deskripsi gambar di sini

Saya tidak akan mengatakan, " Ketika Anda memiliki X MB's " atau " Jika X% dari Ad Hoc Anda Sekali Pakai " untuk mengaktifkannya.
Itu tidak mempengaruhi Sprocs, Pemicu, Tampilan atau Parameterized / SQL Siap - hanya permintaan Ad-Hoc.
Rekomendasi pribadi saya adalah hanya menyalakan di Lingkungan Prod Anda, tetapi pertimbangkan meninggalkannya di Lingkungan Dev Anda.
Saya mengatakan ini hanya untuk Dev, karena jika Anda mengoptimalkan permintaan yang membutuhkan waktu satu menit atau lebih untuk dijalankan, maka Anda tidak ingin menjalankannya 3 kali sebelum Anda dapat melihat seberapa cepat itu akan pergi dengan itu di-cache - setiap satu kali Anda mengeditnya untuk menemukan desain optimasi terbaik.
Jika pekerjaan Anda tidak melibatkan melakukan ini sepanjang hari, maka gila dan minta DBA Anda untuk menyalakannya di mana-mana.

MikeTeeVee
sumber
0

"Mengapa saya TIDAK boleh menggunakan ...." Dalam beberapa investigasi kinerja, menarik rencana keluar dari cache paket mendekati waktu nyata, sambil mengamati pemanfaatan sumber daya bisa sangat membantu. "Optimalkan untuk beban kerja adhoc" dapat mengganggu itu, karena paket rintisan adhoc tidak akan mengembalikan paket ketika menanyakan cache. Dalam kasus seperti itu, jika permintaan dan rencana tidak dapat diidentifikasi, pengaturan dapat dinyalakan dan dinyalakan lagi untuk kepentingan penyelidikan. Perhatikan bahwa perubahan dalam pengaturan efek kueri dikompilasi dari titik itu ke depan. Juga, setiap kali mengubah properti 'server', periksa instance nonprod pada versi yang sama untuk memverifikasi apakah perubahan akan flush cache rencana atau tidak. Saya pribadi benci dikejutkan oleh hal itu. (Misalnya, mengubah maxdop di tingkat server biasanya mem-flush cache paket,

"Rintisan rencana yang dikompilasi tidak memiliki rencana eksekusi yang terkait dengannya dan permintaan untuk pegangan rencana tidak akan mengembalikan XML Showplan." http://technet.microsoft.com/en-us/library/cc645587.aspx

sql_handle
sumber