Bagikan melalui


Memantau Performa Dengan Menggunakan Penyimpanan Kueri

Fitur penyimpanan kueri menyediakan DBA dengan wawasan tentang pilihan dan performa rencana kueri. Ini menyederhanakan pemecahan masalah performa dengan memungkinkan Anda menemukan perbedaan performa yang disebabkan oleh perubahan rencana kueri dengan cepat. Fitur ini secara otomatis mengambil riwayat kueri, paket, dan statistik runtime, dan mempertahankannya untuk tinjauan Anda. Ini memisahkan data menurut jendela waktu, memungkinkan Anda melihat pola penggunaan database dan memahami kapan perubahan rencana kueri terjadi di server. Penyimpanan kueri dapat dikonfigurasi dengan menggunakan opsi UBAH SET DATABASE .

Berlaku untuk: SQL Database V12 (Dapatkan).

Penting

Ini saat ini adalah fitur pratinjau. Untuk menggunakan Penyimpanan Kueri, Anda harus mengakui dan menyetujui bahwa implementasi Penyimpanan Kueri tunduk pada persyaratan pratinjau dalam perjanjian lisensi Anda (misalnya Perjanjian Enterprise, Perjanjian Microsoft Azure, atau Perjanjian Langganan Microsoft Online), serta Ketentuan Penggunaan Tambahan yang berlaku untuk Pratinjau Microsoft Azure.

Mengaktifkan Penyimpanan Kueri

Penyimpanan Kueri tidak aktif untuk database baru secara default.

Dengan Menggunakan Halaman Penyimpanan Kueri di Management Studio

  1. Di Object Explorer, klik kanan database, lalu klik Properti. (Memerlukan Management Studio versi SQL Server 2016.)

  2. Dalam kotak dialog Properti Database , pilih halaman Penyimpanan Kueri .

  3. Dalam kotak Aktifkan , pilih True.

Dengan Menggunakan Pernyataan Transact-SQL

  1. ALTER DATABASE Gunakan pernyataan untuk mengaktifkan penyimpanan kueri. Contohnya:

    ALTER DATABASE AdventureWorks2012 SET QUERY_STORE = ON;
    

    Untuk opsi sintaks lainnya yang terkait dengan penyimpanan kueri, lihat MENGUBAH Opsi SET DATABASE (Transact-SQL).

Catatan

Anda tidak dapat mengaktifkan penyimpanan kueri untuk database master.

Informasi di Penyimpanan Kueri

Rencana eksekusi untuk kueri tertentu dalam SQL Server biasanya berkembang dari waktu ke waktu karena sejumlah alasan yang berbeda seperti perubahan statistik, perubahan skema, pembuatan/penghapusan indeks, dll. Cache prosedur (tempat rencana kueri yang di-cache disimpan) hanya menyimpan rencana eksekusi terbaru. Rencana juga dikeluarkan dari cache rencana karena tekanan memori. Akibatnya, regresi performa kueri yang disebabkan oleh perubahan rencana eksekusi dapat tidak sepele dan memakan waktu untuk diselesaikan.

Karena penyimpanan kueri mempertahankan beberapa rencana eksekusi per kueri, penyimpanan kueri dapat memberlakukan kebijakan untuk mengarahkan prosesor kueri menggunakan rencana eksekusi tertentu untuk kueri. Ini disebut sebagai memaksa rencana. Paket memaksa di Penyimpanan Kueri disediakan dengan menggunakan mekanisme yang mirip dengan petunjuk kueri USE PLAN , tetapi tidak memerlukan perubahan apa pun dalam aplikasi pengguna. Pemakaian rencana dapat mengatasi regresi performa kueri yang disebabkan oleh perubahan rencana dalam waktu yang sangat singkat.

Skenario umum untuk menggunakan fitur Penyimpanan Kueri adalah:

  • Temukan dan perbaiki regresi performa rencana dengan cepat dengan memaksa rencana kueri sebelumnya. Perbaiki kueri yang baru-baru ini mengalami kemunculan performa karena perubahan rencana eksekusi.

  • Tentukan berapa kali kueri dijalankan di jendela waktu tertentu, membantu DBA dalam memecahkan masalah sumber daya performa.

  • Identifikasi kueri n teratas (berdasarkan waktu eksekusi, konsumsi memori, dll.) dalam x jam terakhir.

  • Mengaudit riwayat rencana kueri untuk kueri tertentu.

  • Analisis pola penggunaan sumber daya (CPU, I/O, dan Memori) untuk database tertentu.

Penyimpanan kueri berisi dua penyimpanan; penyimpanan rencana untuk mempertahankan informasi rencana eksekusi, dan penyimpanan statistik runtime untuk mempertahankan informasi statistik eksekusi. Jumlah paket unik yang dapat disimpan untuk kueri di penyimpanan paket dibatasi oleh max_plans_per_query opsi konfigurasi. Untuk meningkatkan performa, informasi ditulis ke dua toko secara asinkron. Untuk meminimalkan penggunaan ruang, statistik eksekusi runtime di penyimpanan statistik runtime dikumpulkan selama jendela waktu tetap. Informasi di penyimpanan ini terlihat dengan mengkueri tampilan katalog penyimpanan kueri.

Kueri berikut mengembalikan informasi tentang kueri dan paket di penyimpanan kueri.

SELECT Txt.query_text_id, Txt.query_sql_text, Pl.plan_id, Qry.*
FROM sys.query_store_plan AS Pl
JOIN sys.query_store_query AS Qry
    ON Pl.query_id = Qry.query_id
JOIN sys.query_store_query_text AS Txt
    ON Qry.query_text_id = Txt.query_text_id ;

Menggunakan Fitur Kueri yang Diregresi

Setelah mengaktifkan penyimpanan kueri, refresh bagian database panel Object Explorer untuk menambahkan bagian Penyimpanan Kueri.

QueryStore

Memilih Kueri yang Diregresi, membuka panel Kueri yang Diregresi di Management Studio. Panel Kueri yang Diregresi memperlihatkan kueri, dan paket di penyimpanan kueri. Kotak drop-down di bagian atas memungkinkan Anda memilih kueri berdasarkan berbagai kriteria. Pilih rencana untuk melihat rencana kueri grafis. Tombol tersedia untuk menampilkan kueri sumber, memaksa, dan menerapkan rencana kueri, dan me-refresh tampilan.

RegressedQueries

Untuk memaksa rencana, pilih kueri dan rencana, lalu klik Paksa Rencanakan. Anda hanya bisa memaksa paket yang disimpan oleh fitur rencana kueri dan masih dipertahankan dalam cache rencana kueri.

Opsi Konfigurasi

OPERATION_MODE Dapat READ_WRITE atau READ_ONLY.

CLEANUP_POLICY Mengonfigurasi argumen STALE_QUERY_THRESHOLD_DAYS untuk menentukan jumlah hari untuk menyimpan data di penyimpanan kueri.

DATA_FLUSH_INTERVAL_SECONDS Menentukan frekuensi data yang ditulis ke penyimpanan kueri dipertahankan ke disk. Untuk mengoptimalkan performa, data yang dikumpulkan oleh penyimpanan kueri ditulis secara asinkron ke disk. Frekuensi di mana transfer asinkron ini terjadi dikonfigurasi melalui DATA_FLUSH_INTERVAL_SECONDS.

MAX_SIZE_MB Mengonfigurasi ukuran maksimum penyimpanan kueri. Jika data di penyimpanan kueri mencapai batas MAX_SIZE_MB, penyimpanan kueri secara otomatis mengubah status dari baca-tulis menjadi baca-saja dan berhenti mengumpulkan data baru.

INTERVAL_LENGTH_MINUTES Menentukan interval waktu di mana data statistik eksekusi runtime dikumpulkan ke dalam penyimpanan kueri. Untuk mengoptimalkan penggunaan ruang, statistik eksekusi runtime di Penyimpanan Statistik Runtime dikumpulkan selama jendela waktu tetap. Jendela waktu tetap ini dikonfigurasi melalui INTERVAL_LENGTH_MINUTES.

sys.database_query_store_options Kueri tampilan untuk menentukan opsi penyimpanan kueri saat ini.

Untuk informasi selengkapnya tentang mengatur opsi dengan menggunakan pernyataan Transact-SQL, lihat Manajemen Opsi.

Penyimpanan Kueri dapat dilihat dan dikelola melalui Management Studio atau dengan menggunakan tampilan dan prosedur berikut.

Tampilan Katalog Penyimpanan Kueri

Tujuh tampilan katalog menyajikan informasi tentang Penyimpanan Kueri.

Prosedur Tersimpan Penyimpanan Kueri

Enam prosedur tersimpan mengonfigurasi Penyimpanan Kueri.

Skenario Penggunaan Kunci

Manajemen Opsi

Bagian ini menyediakan beberapa panduan tentang mengelola fitur Penyimpanan Kueri itu sendiri.

Apakah Penyimpanan Kueri saat ini aktif?

Penyimpanan Kueri menyimpan datanya di dalam database pengguna dan itulah sebabnya memiliki batas ukuran (dikonfigurasi dengan MAX_STORAGE_SIZE_MB). Jika data di Penyimpanan Kueri mencapai batas tersebut, Penyimpanan Kueri akan secara otomatis mengubah status dari baca-tulis menjadi baca-saja dan berhenti mengumpulkan data baru.

Jalankan skrip berikut untuk menentukan apakah Penyimpanan Kueri saat ini aktif, dan apakah saat ini mengumpulkan statistik runtime atau tidak.

DECLARE @x nvarchar(100) = CAST(newid() AS nvarchar(100));
DECLARE @query nvarchar(max) = 
N'IF EXISTS
(
    SELECT * 
    FROM sys.query_store_query_text 
    WHERE query_sql_text LIKE ''%' + @x + N'%''
)
SELECT ''Query Store is active'' ;
ELSE SELECT ''Query Store is NOT active''' ;
EXEC sp_executesql @query;

Opsi Dapatkan Penyimpanan Kueri

Untuk mengetahui informasi terperinci tentang status Penyimpanan Kueri, jalankan mengikuti dalam database pengguna.

SELECT * FROM sys.database_query_store_options;

Mengatur interval Penyimpanan Kueri

Anda dapat mengambil alih interval untuk menggabungkan statistik runtime kueri (defaultnya adalah 60 menit).


      USE master;
GO

ALTER DATABASE <database_name> 
SET QUERY_STORE (INTERVAL_LENGTH_MINUTES = 15);

Perhatikan bahwa nilai arbitrer tidak diizinkan - Anda harus menggunakan salah satu hal berikut: 1, 5, 10, 15, 30 dan 60.

Nilai baru untuk interval diekspos melalui sys.database_query_store_options tampilan.

Jika penyimpanan Penyimpanan Kueri penuh, gunakan pernyataan berikut untuk memperluas penyimpanan.

ALTER DATABASE <database_name> 
SET QUERY_STORE (MAX_STORAGE_SIZE_MB = <new_size>);

Mengatur semua opsi Penyimpanan Kueri

Anda bisa mengatur beberapa opsi Penyimpanan Kueri sekaligus dengan satu pernyataan ALTER DATABASE.

ALTER DATABASE <database name> 
SET QUERY_STORE (
    OPERATION_MODE = READ_WRITE,
    CLEANUP_POLICY = 
    (STALE_QUERY_THRESHOLD_DAYS = 30),
    DATA_FLUSH_INTERVAL_SECONDS = 3000,
    MAX_STORAGE_SIZE_MB = 500,
    INTERVAL_LENGTH_MINUTES = 15
);

Membersihkan ruang

Tabel internal Penyimpanan Kueri dibuat di grup file PRIMARY selama pembuatan database dan konfigurasi tersebut tidak dapat diubah nanti. Jika Anda kehabisan ruang, Anda mungkin ingin menghapus data Penyimpanan Kueri yang lebih lama dengan menggunakan pernyataan berikut.

ALTER DATABASE <db_name> SET QUERY_STORE CLEAR;

Atau, Anda mungkin hanya ingin menghapus data kueri ad-hoc, karena kurang relevan untuk pengoptimalan kueri dan analisis rencana tetapi membutuhkan ruang yang sama banyaknya.

Menghapus kueri ad-hoc Ini menghapus kueri yang hanya dijalankan sekali dan yang berusia lebih dari 24 jam.

DECLARE @id int
DECLARE adhoc_queries_cursor CURSOR 
FOR 
SELECT q.query_id
FROM sys.query_store_query_text AS qt
JOIN sys.query_store_query AS q 
    ON q.query_text_id = qt.query_text_id
JOIN sys.query_store_plan AS p 
    ON p.query_id = q.query_id
JOIN sys.query_store_runtime_stats AS rs 
    ON rs.plan_id = p.plan_id
GROUP BY q.query_id
HAVING SUM(rs.count_executions) < 2 
AND MAX(rs.last_execution_time) < DATEADD (hour, -24, GETUTCDATE())
ORDER BY q.query_id ;

OPEN adhoc_queries_cursor ;
FETCH NEXT FROM adhoc_queries_cursor INTO @id;
WHILE @@fetch_status = 0
    BEGIN 
        PRINT @id
        EXEC sp_query_store_remove_query @id
        FETCH NEXT FROM adhoc_queries_cursor INTO @id
    END 
CLOSE adhoc_queries_cursor ;
DEALLOCATE adhoc_queries_cursor;

Anda dapat menentukan prosedur Anda sendiri dengan logika yang berbeda untuk membersihkan data yang tidak lagi penting bagi Anda.

Contoh di atas menggunakan sp_query_store_remove_query prosedur tersimpan yang diperluas untuk menghapus data yang tidak perlu. Anda juga dapat menggunakan dua prosedur lainnya.

  • sp_query_store_reset_exec_stats - statistik runtime yang jelas untuk rencana tertentu.

  • sp_query_store_remove_plan - menghapus satu paket.

Audit dan Pemecahan Masalah Performa

Karena Penyimpanan Kueri menyimpan riwayat kompilasi dan metrik runtime sepanjang eksekusi kueri, ada banyak pertanyaan berbeda yang dapat Anda jawab dengan mudah sehubungan dengan beban kerja Anda.

Kueri n terakhir dijalankan pada database.

SELECT TOP 10 qt.query_sql_text, q.query_id, 
    qt.query_text_id, p.plan_id, rs.last_execution_time
FROM sys.query_store_query_text AS qt 
JOIN sys.query_store_query AS q 
    ON qt.query_text_id = q.query_text_id 
JOIN sys.query_store_plan AS p 
    ON q.query_id = p.query_id 
JOIN sys.query_store_runtime_stats AS rs 
    ON p.plan_id = rs.plan_id
ORDER BY rs.last_execution_time DESC;

Jumlah eksekusi untuk setiap kueri.

SELECT q.query_id, qt.query_text_id, qt.query_sql_text, 
    SUM(rs.count_executions) AS total_execution_count
FROM sys.query_store_query_text AS qt 
JOIN sys.query_store_query AS q 
    ON qt.query_text_id = q.query_text_id 
JOIN sys.query_store_plan AS p 
    ON q.query_id = p.query_id 
JOIN sys.query_store_runtime_stats AS rs 
    ON p.plan_id = rs.plan_id
GROUP BY q.query_id, qt.query_text_id, qt.query_sql_text
ORDER BY total_execution_count DESC;

Jumlah kueri dengan waktu eksekusi rata-rata terpanjang dalam satu jam terakhir.

SELECT TOP 10 rs.avg_duration, qt.query_sql_text, q.query_id,
    qt.query_text_id, p.plan_id, GETUTCDATE() AS CurrentUTCTime, 
    rs.last_execution_time 
FROM sys.query_store_query_text AS qt 
JOIN sys.query_store_query AS q 
    ON qt.query_text_id = q.query_text_id 
JOIN sys.query_store_plan AS p 
    ON q.query_id = p.query_id 
JOIN sys.query_store_runtime_stats AS rs 
    ON p.plan_id = rs.plan_id
WHERE rs.last_execution_time > DATEADD(hour, -1, GETUTCDATE())
ORDER BY rs.avg_duration DESC;

Jumlah kueri yang memiliki pembacaan IO fisik rata-rata terbesar dalam 24 jam terakhir, dengan jumlah baris rata-rata dan jumlah eksekusi yang sesuai.

SELECT TOP 10 rs.avg_physical_io_reads, qt.query_sql_text, 
    q.query_id, qt.query_text_id, p.plan_id, rs.runtime_stats_id, 
    rsi.start_time, rsi.end_time, rs.avg_rowcount, rs.count_executions
FROM sys.query_store_query_text AS qt 
JOIN sys.query_store_query AS q 
    ON qt.query_text_id = q.query_text_id 
JOIN sys.query_store_plan AS p 
    ON q.query_id = p.query_id 
JOIN sys.query_store_runtime_stats AS rs 
    ON p.plan_id = rs.plan_id 
JOIN sys.query_store_runtime_stats_interval AS rsi 
    ON rsi.runtime_stats_interval_id = rs.runtime_stats_interval_id
WHERE rsi.start_time >= DATEADD(hour, -24, GETUTCDATE()) 
ORDER BY rs.avg_physical_io_reads DESC;

Kueri dengan beberapa paket. Kueri ini sangat menarik karena mereka adalah kandidat untuk regresi karena perubahan pilihan rencana. Kueri berikut mengidentifikasi kueri ini bersama dengan semua paket:

WITH Query_MultPlans
AS
(
    SELECT COUNT(*) AS cnt, q.query_id 
    FROM sys.query_store_query_text AS qt
    JOIN sys.query_store_query AS q
        ON qt.query_text_id = q.query_text_id
    JOIN sys.query_store_plan AS p
        ON p.query_id = q.query_id
    GROUP BY q.query_id
    HAVING COUNT(distinct plan_id) > 1
)

SELECT q.query_id, object_name(object_id) AS ContainingObject, query_sql_text,
plan_id, p.query_plan AS plan_xml,
p.last_compile_start_time, p.last_execution_time
FROM Query_MultPlans AS qm
JOIN sys.query_store_query AS q
    ON qm.query_id = q.query_id
JOIN sys.query_store_plan AS p
    ON q.query_id = p.query_id
JOIN sys.query_store_query_text qt 
    ON qt.query_text_id = q.query_text_id
ORDER BY query_id, plan_id;

Kueri yang baru-baru ini memuncak dalam performa (membandingkan titik waktu yang berbeda). Contoh kueri berikut mengembalikan semua kueri yang waktu eksekusinya dua kali lipat dalam 48 jam terakhir karena perubahan pilihan paket. Kueri membandingkan semua interval statistik runtime berdampingan.

SELECT 
    qt.query_sql_text, 
    q.query_id, 
    qt.query_text_id, 
    rs1.runtime_stats_id AS runtime_stats_id_1,
    rsi1.start_time AS interval_1, 
    p1.plan_id AS plan_1, 
    rs1.avg_duration AS avg_duration_1, 
    rs2.avg_duration AS avg_duration_2,
    p2.plan_id AS plan_2, 
    rsi2.start_time AS interval_2, 
    rs2.runtime_stats_id AS runtime_stats_id_2
FROM sys.query_store_query_text AS qt 
JOIN sys.query_store_query AS q 
    ON qt.query_text_id = q.query_text_id 
JOIN sys.query_store_plan AS p1 
    ON q.query_id = p1.query_id 
JOIN sys.query_store_runtime_stats AS rs1 
    ON p1.plan_id = rs1.plan_id 
JOIN sys.query_store_runtime_stats_interval AS rsi1 
    ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id 
JOIN sys.query_store_plan AS p2 
    ON q.query_id = p2.query_id 
JOIN sys.query_store_runtime_stats AS rs2 
    ON p2.plan_id = rs2.plan_id 
JOIN sys.query_store_runtime_stats_interval AS rsi2 
    ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
WHERE rsi1.start_time > DATEADD(hour, -48, GETUTCDATE()) 
    AND rsi2.start_time > rsi1.start_time 
    AND p1.plan_id <> p2.plan_id
    AND rs2.avg_duration > 2*rs1.avg_duration
ORDER BY q.query_id, rsi1.start_time, rsi2.start_time;

Jika Anda ingin melihat performa semua regresi (tidak hanya yang terkait dengan perubahan pilihan rencana) daripada hanya menghapus kondisi AND p1.plan_id <> p2.plan_id dari kueri sebelumnya.

Kueri yang baru-baru ini mengalami kemunduran performa (membandingkan eksekusi riwayat terbaru vs. ). Kueri berikutnya membandingkan periode eksekusi kueri berdasarkan eksekusi. Dalam contoh khusus ini kueri membandingkan eksekusi dalam periode terbaru (1 jam) vs. periode riwayat (hari terakhir) dan mengidentifikasi yang memperkenalkan additional_duration_workload. Metrik ini dihitung sebagai perbedaan antara eksekusi rata-rata terbaru dan eksekusi rata-rata riwayat dikalikan dengan jumlah eksekusi terbaru. Ini benar-benar mewakili berapa banyak durasi tambahan eksekusi terbaru yang diperkenalkan dibandingkan dengan riwayat:

--- "Recent" workload - last 1 hour
DECLARE @recent_start_time datetimeoffset;
DECLARE @recent_end_time datetimeoffset;
SET @recent_start_time = DATEADD(hour, -1, SYSUTCDATETIME());
SET @recent_end_time = SYSUTCDATETIME();

--- "History" workload
DECLARE @history_start_time datetimeoffset;
DECLARE @history_end_time datetimeoffset;
SET @history_start_time = DATEADD(hour, -24, SYSUTCDATETIME());
SET @history_end_time = SYSUTCDATETIME();

WITH
hist AS
(
    SELECT 
        p.query_id query_id, 
        CONVERT(float, SUM(rs.avg_duration*rs.count_executions)) total_duration, 
        SUM(rs.count_executions) count_executions,
        COUNT(distinct p.plan_id) num_plans 
     FROM sys.query_store_runtime_stats AS rs
        JOIN sys.query_store_plan p ON p.plan_id = rs.plan_id
    WHERE  (rs.first_execution_time >= @history_start_time AND rs.last_execution_time < @history_end_time)
        OR (rs.first_execution_time <= @history_start_time AND rs.last_execution_time > @history_start_time)
        OR (rs.first_execution_time <= @history_end_time AND rs.last_execution_time > @history_end_time)
    GROUP BY p.query_id
),
recent AS
(
    SELECT 
        p.query_id query_id, 
        CONVERT(float, SUM(rs.avg_duration*rs.count_executions)) total_duration, 
        SUM(rs.count_executions) count_executions,
        COUNT(distinct p.plan_id) num_plans 
    FROM sys.query_store_runtime_stats AS rs
        JOIN sys.query_store_plan p ON p.plan_id = rs.plan_id
    WHERE  (rs.first_execution_time >= @recent_start_time AND rs.last_execution_time < @recent_end_time)
        OR (rs.first_execution_time <= @recent_start_time AND rs.last_execution_time > @recent_start_time)
        OR (rs.first_execution_time <= @recent_end_time AND rs.last_execution_time > @recent_end_time)
    GROUP BY p.query_id
)
SELECT 
    results.query_id query_id,
    results.query_text query_text,
    results.additional_duration_workload additional_duration_workload,
    results.total_duration_recent total_duration_recent,
    results.total_duration_hist total_duration_hist,
    ISNULL(results.count_executions_recent, 0) count_executions_recent,
    ISNULL(results.count_executions_hist, 0) count_executions_hist 
FROM
(
    SELECT
        hist.query_id query_id,
        qt.query_sql_text query_text,
        ROUND(CONVERT(float, recent.total_duration/recent.count_executions-hist.total_duration/hist.count_executions)*(recent.count_executions), 2) AS additional_duration_workload,
        ROUND(recent.total_duration, 2) total_duration_recent, 
        ROUND(hist.total_duration, 2) total_duration_hist,
        recent.count_executions count_executions_recent,
        hist.count_executions count_executions_hist   
    FROM hist 
        JOIN recent 
            ON hist.query_id = recent.query_id 
        JOIN sys.query_store_query AS q 
            ON q.query_id = hist.query_id
        JOIN sys.query_store_query_text AS qt 
            ON q.query_text_id = qt.query_text_id    
) AS results
WHERE additional_duration_workload > 0
ORDER BY additional_duration_workload DESC
OPTION (MERGE JOIN);

Mempertahankan Stabilitas Performa Kueri

Untuk kueri yang dijalankan beberapa kali, Anda mungkin melihat bahwa SQL Server menggunakan paket yang berbeda yang menghasilkan pemanfaatan dan durasi sumber daya yang berbeda. Dengan Penyimpanan Kueri, Anda dapat dengan mudah mendeteksi kapan performa kueri mengalami kemunculan dan menentukan rencana optimal dalam periode yang diminati. Kemudian Anda dapat memaksa rencana optimal itu untuk eksekusi kueri di masa mendatang.

Anda juga dapat mengidentifikasi performa kueri yang tidak konsisten untuk kueri dengan parameter (baik parameter otomatis atau parameternya secara manual). Di antara berbagai rencana, Anda dapat mengidentifikasi rencana yang cukup cepat dan optimal untuk semua atau sebagian besar nilai parameter dan memaksa rencana tersebut; menjaga performa yang dapat diprediksi untuk serangkaian skenario pengguna yang lebih luas.

Paksa atau rencana untuk kueri (terapkan kebijakan pemaksaan). Ketika rencana dipaksa untuk kueri tertentu, setiap kali kueri datang ke eksekusi, kueri akan dijalankan dengan rencana yang dipaksa.

EXEC sp_query_store_force_plan @query_id = 48, @plan_id = 49;

Saat menggunakan sp_query_store_force_plan Anda hanya bisa memaksa paket yang direkam oleh Penyimpanan Kueri sebagai rencana untuk kueri tersebut. Dengan kata lain, satu-satunya paket yang tersedia untuk kueri adalah paket yang sudah digunakan untuk menjalankan Q1 saat Penyimpanan Kueri aktif.

Menghapus paksa paket untuk kueri. Untuk mengandalkan pengoptimal kueri SQL Server lagi untuk menghitung rencana kueri yang optimal, gunakan sp_query_store_unforce_plan untuk membatalkan penerapan rencana yang dipilih untuk kueri.

EXEC sp_query_store_unforce_plan @query_id = 48, @plan_id = 49;

Lihat juga

Memantau dan MenyetelPemantauan Performa dan Alat PenyetelanBuka Monitor Aktivitas (SQL Server Management Studio)Monitor Aktivitas