Bagaimana cara mendapatkan paket eksekusi kueri di SQL Server?


338

Di Microsoft SQL Server bagaimana saya bisa mendapatkan rencana eksekusi permintaan untuk prosedur query / tersimpan?


2
Bagaimana cara menutup tab Rencana Pelaksanaan di studio manajemen server SQL?
Paul McCarthy

2
@ Paul Anda dapat menekan Ctrl + R untuk itu. Itu menutup bagian seluruh hasil - termasuk pesan dan rencana eksekusi.
Nisarg

Jawaban:


502

Ada sejumlah metode untuk mendapatkan rencana eksekusi, yang akan digunakan tergantung pada keadaan Anda. Biasanya Anda dapat menggunakan SQL Server Management Studio untuk mendapatkan paket, namun jika karena alasan tertentu Anda tidak dapat menjalankan kueri di SQL Server Management Studio maka Anda mungkin merasa terbantu untuk dapat memperoleh paket melalui SQL Server Profiler atau dengan memeriksa cache rencana.

Metode 1 - Menggunakan SQL Server Management Studio

SQL Server hadir dengan beberapa fitur rapi yang membuatnya sangat mudah untuk menangkap rencana eksekusi, cukup pastikan bahwa item menu "Sertakan Rencana Eksekusi Aktual" (ditemukan di bawah menu "Permintaan") dicentang dan jalankan kueri Anda seperti biasa .

Sertakan item menu Rencana Eksekusi Aksi

Jika Anda mencoba untuk mendapatkan rencana eksekusi untuk pernyataan dalam prosedur tersimpan, maka Anda harus menjalankan prosedur tersimpan, seperti:

exec p_Example 42

Ketika kueri Anda selesai, Anda akan melihat tab tambahan berjudul "Rencana eksekusi" muncul di panel hasil. Jika Anda menjalankan banyak pernyataan, Anda mungkin melihat banyak paket ditampilkan di tab ini.

Cuplikan layar dari Rencana Eksekusi

Dari sini Anda dapat memeriksa paket eksekusi di SQL Server Management Studio, atau klik kanan pada paket tersebut dan pilih "Simpan Paket Eksekusi Sebagai ..." untuk menyimpan paket ke file dalam format XML.

Metode 2 - Menggunakan opsi SHOWPLAN

Metode ini sangat mirip dengan metode 1 (sebenarnya inilah yang dilakukan SQL Server Management Studio secara internal), namun saya telah memasukkannya untuk kelengkapan atau jika Anda tidak memiliki SQL Server Management Studio yang tersedia.

Sebelum Anda menjalankan kueri, jalankan salah satu dari pernyataan berikut. Pernyataan harus merupakan satu-satunya pernyataan dalam kumpulan, yaitu Anda tidak dapat menjalankan pernyataan lain secara bersamaan:

SET SHOWPLAN_TEXT ON
SET SHOWPLAN_ALL ON
SET SHOWPLAN_XML ON
SET STATISTICS PROFILE ON
SET STATISTICS XML ON -- The is the recommended option to use

Ini adalah opsi koneksi dan Anda hanya perlu menjalankan ini sekali per koneksi. Dari titik ini pada semua pernyataan dijalankan akan disertai oleh resultset tambahan berisi rencana eksekusi Anda dalam format yang diinginkan - jalankan saja permintaan Anda seperti biasanya melihat paket.

Setelah selesai, Anda dapat mematikan opsi ini dengan pernyataan berikut:

SET <<option>> OFF

Perbandingan format rencana eksekusi

Kecuali Anda memiliki preferensi yang kuat, rekomendasi saya adalah menggunakan STATISTICS XMLopsi. Opsi ini setara dengan opsi "Sertakan Rencana Eksekusi Aktual" di SQL Server Management Studio dan memasok sebagian besar informasi dalam format yang paling nyaman.

  • SHOWPLAN_TEXT - Menampilkan perkiraan rencana eksekusi berdasarkan teks, tanpa menjalankan kueri
  • SHOWPLAN_ALL - Menampilkan estimasi rencana eksekusi berdasarkan teks dengan estimasi biaya, tanpa mengeksekusi kueri
  • SHOWPLAN_XML- Menampilkan rencana eksekusi estimasi berbasis XML dengan estimasi biaya, tanpa mengeksekusi query. Ini sama dengan opsi "Tampilkan Perkiraan Rencana Eksekusi ..." di SQL Server Management Studio.
  • STATISTICS PROFILE - Mengeksekusi kueri dan menampilkan rencana eksekusi aktual berbasis teks.
  • STATISTICS XML- Menjalankan query dan menampilkan rencana eksekusi aktual berbasis XML. Ini sama dengan opsi "Sertakan Rencana Eksekusi Aktual" di SQL Server Management Studio.

Metode 3 - Menggunakan SQL Server Profiler

Jika Anda tidak dapat menjalankan kueri Anda secara langsung (atau kueri Anda tidak berjalan lambat ketika Anda menjalankannya secara langsung - ingat kami ingin rencana permintaan berkinerja buruk), maka Anda dapat menangkap rencana menggunakan jejak SQL Server Profiler. Idenya adalah menjalankan kueri Anda saat jejak yang menangkap salah satu acara "Showplan" sedang berjalan.

Perhatikan bahwa tergantung pada beban Anda dapat menggunakan metode ini pada lingkungan produksi, namun Anda harus berhati-hati. Mekanisme profil SQL Server dirancang untuk meminimalkan dampak pada database tetapi ini tidak berarti bahwa tidak akan ada dampak kinerja. Anda juga mungkin mengalami masalah dalam memfilter dan mengidentifikasi rencana yang benar dalam penelusuran Anda jika basis data Anda banyak digunakan. Anda jelas harus memeriksa dengan DBA Anda untuk melihat apakah mereka senang dengan Anda melakukan ini pada database berharga mereka!

  1. Buka SQL Server Profiler dan buat jejak baru yang menghubungkan ke database yang diinginkan yang ingin Anda rekam jejaknya.
  2. Di bawah tab "Pemilihan Acara" centang "Tampilkan semua acara", centang baris "Kinerja" -> "Showplan XML" dan jalankan jejaknya.
  3. Saat jejak sedang berjalan, lakukan apa yang perlu Anda lakukan untuk menjalankan kueri yang berjalan lambat.
  4. Tunggu kueri untuk menyelesaikan dan menghentikan jejak.
  5. Untuk menyimpan jejak klik kanan pada paket xml di SQL Server Profiler dan pilih "Ekstrak data acara ..." untuk menyimpan paket ke file dalam format XML.

Paket yang Anda dapatkan setara dengan opsi "Sertakan Rencana Eksekusi Aktual" di SQL Server Management Studio.

Metode 4 - Memeriksa cache kueri

Jika Anda tidak dapat menjalankan kueri Anda secara langsung dan Anda juga tidak dapat menangkap jejak profiler maka Anda masih dapat memperoleh rencana yang diperkirakan dengan memeriksa cache paket permintaan SQL.

Kami memeriksa cache paket dengan menanyakan SQL Server DMVs . Berikut ini adalah permintaan dasar yang akan mencantumkan semua paket permintaan yang di-cache (sebagai xml) bersama dengan teks SQL-nya. Pada sebagian besar basis data, Anda juga perlu menambahkan klausa pemfilteran tambahan untuk memfilter hasilnya ke hanya paket yang Anda minati.

SELECT UseCounts, Cacheobjtype, Objtype, TEXT, query_plan
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)

Jalankan permintaan ini dan klik pada paket XML untuk membuka paket di jendela baru - klik kanan dan pilih "Simpan paket eksekusi sebagai ..." untuk menyimpan paket ke file dalam format XML.

Catatan:

Karena ada begitu banyak faktor yang terlibat (mulai dari tabel dan skema indeks hingga data yang disimpan dan statistik tabel) Anda harus selalu mencoba untuk mendapatkan rencana eksekusi dari database yang Anda minati (biasanya yang mengalami kinerja masalah).

Anda tidak dapat menangkap rencana eksekusi untuk prosedur tersimpan terenkripsi.

rencana eksekusi "aktual" vs "diperkirakan"

Sebuah sebenarnya rencana eksekusi adalah salah satu di mana SQL Server benar-benar berjalan query, sedangkan diperkirakan rencana eksekusi SQL Server bekerja di luar apa yang akan lakukan tanpa mengeksekusi query. Meskipun secara logika setara, rencana eksekusi aktual jauh lebih berguna karena berisi detail dan statistik tambahan tentang apa yang sebenarnya terjadi ketika menjalankan kueri. Ini penting ketika mendiagnosis masalah di mana estimasi SQL Server tidak aktif (seperti ketika statistik kedaluwarsa).

Bagaimana cara menginterpretasikan rencana eksekusi permintaan?

Ini adalah cukup layak topik untuk (gratis) buku dalam dirinya sendiri.

Lihat juga:


8
Catatan untuk pembaca masa depan: masukkan SET STATISTICS XML ONsemut awal kueri, dan SET STATISTICS XML OFF|ONarea sekitarnya yang tidak ingin Anda tampilkan dalam output paket: Saya menemukan ini berguna ketika kueri berisi iterasi (WHILE) yang tidak Anda inginkan / butuhkan untuk melihat dalam rencana eksekusi (jika tidak akan terlalu berat dan panjang untuk SQL SERVER untuk menampilkannya).
Roimer

2
@MonsterMMORPG Anda dapat menggunakan metode 4 dan kemudian PILIH. Misalnya, menggunakan <a href=" github.com/StackExchange/dapper-dot-net"> Dapper.net </… > koneksi. Permintaan <string> ("SELECT query_plan FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text (plan_handle) ) LINTAS BERLAKU sys.dm_exec_query_plan (plan_handle) DIMANA TEKS SEPERTI N '% Kueri Asli Anda Datang Di Sini%' "); % Adalah jika Anda hanya menggunakan sebagian dari kueri Anda.
tanda

2
@Justin edisi kedua buku yang Anda tautkan, untuk menafsirkan rencana eksekusi kueri, bertanggal dari 2009. Apakah Anda masih mengatakan bahwa itu adalah sumber yang sangat bagus untuk tujuan itu pada tahun 2016?
Abdul

3
@Abdul Penulis yang sama, Grant Fritchey, memiliki buku yang lebih baru bernama SQL Server Query Performance Tuning yang mencakup versi SQL Server yang lebih baru.
thelem

42

Selain jawaban komprehensif yang sudah diposting kadang-kadang berguna untuk dapat mengakses rencana eksekusi secara sistematis untuk mengekstrak informasi. Contoh kode untuk ini adalah di bawah ini.

DECLARE @TraceID INT
EXEC StartCapture @@SPID, @TraceID OUTPUT
EXEC sp_help 'sys.objects' /*<-- Call your stored proc of interest here.*/
EXEC StopCapture @TraceID

Contoh StartCaptureDefinisi

CREATE PROCEDURE StartCapture
@Spid INT,
@TraceID INT OUTPUT
AS
DECLARE @maxfilesize BIGINT = 5
DECLARE @filepath NVARCHAR(200) = N'C:\trace_' + LEFT(NEWID(),36)

EXEC sp_trace_create @TraceID OUTPUT, 0, @filepath, @maxfilesize, NULL 

exec sp_trace_setevent @TraceID, 122, 1, 1
exec sp_trace_setevent @TraceID, 122, 22, 1
exec sp_trace_setevent @TraceID, 122, 34, 1
exec sp_trace_setevent @TraceID, 122, 51, 1
exec sp_trace_setevent @TraceID, 122, 12, 1
-- filter for spid
EXEC sp_trace_setfilter @TraceID, 12, 0, 0, @Spid
-- start the trace
EXEC sp_trace_setstatus @TraceID, 1

Contoh StopCaptureDefinisi

CREATE  PROCEDURE StopCapture
@TraceID INT
AS
WITH  XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as sql), 
      CTE
     as (SELECT CAST(TextData AS VARCHAR(MAX)) AS TextData,
                ObjectID,
                ObjectName,
                EventSequence,
                /*costs accumulate up the tree so the MAX should be the root*/
                MAX(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
         FROM   fn_trace_getinfo(@TraceID) fn
                CROSS APPLY fn_trace_gettable(CAST(value AS NVARCHAR(200)), 1)
                CROSS APPLY (SELECT CAST(TextData AS XML) AS xPlan) x
                CROSS APPLY (SELECT T.relop.value('@EstimatedTotalSubtreeCost',
                                            'float') AS EstimatedTotalSubtreeCost
                             FROM   xPlan.nodes('//sql:RelOp') T(relop)) ca
         WHERE  property = 2
                AND TextData IS NOT NULL
                AND ObjectName not in ( 'StopCapture', 'fn_trace_getinfo' )
         GROUP  BY CAST(TextData AS VARCHAR(MAX)),
                   ObjectID,
                   ObjectName,
                   EventSequence)
SELECT ObjectName,
       SUM(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
FROM   CTE
GROUP  BY ObjectID,
          ObjectName  

-- Stop the trace
EXEC sp_trace_setstatus @TraceID, 0
-- Close and delete the trace
EXEC sp_trace_setstatus @TraceID, 2
GO

18

Dengan asumsi Anda menggunakan Microsoft SQL Server Management Studio

  • Untuk Perkiraan Rencana Kueri Anda dapat menekan Ctrl + L atau tombol berikut.

masukkan deskripsi gambar di sini

  • Untuk Rencana Kueri Aktual , Anda dapat menekan Ctrl + M atau tombol berikut sebelum menjalankan kueri.

masukkan deskripsi gambar di sini

  • Untuk Rencana Kueri Langsung , (hanya di SSMS 2016) gunakan tombol berikut sebelum menjalankan kueri.

masukkan deskripsi gambar di sini


15

Selain metode yang dijelaskan dalam jawaban sebelumnya, Anda juga dapat menggunakan penampil paket eksekusi gratis dan alat optimisasi kueri ApexSQL Plan (yang baru saja saya bahas).

Anda dapat menginstal dan mengintegrasikan Rencana ApexSQL ke dalam SQL Server Management Studio, sehingga rencana eksekusi dapat dilihat dari SSMS secara langsung.

Melihat Perkiraan rencana eksekusi di Paket ApexSQL

  1. Klik tombol Permintaan Baru di SSMS dan rekatkan teks kueri di jendela teks kueri. Klik kanan dan pilih opsi "Tampilkan Perkiraan Rencana Eksekusi" dari menu konteks.

Tombol Permintaan baru di SSMS

  1. Diagram rencana eksekusi akan ditampilkan tab Rencana Eksekusi di bagian hasil. Selanjutnya klik kanan rencana eksekusi dan di menu konteks pilih opsi "Buka di ApexSQL Rencana".

Rencana eksekusi

  1. Perkiraan rencana eksekusi akan dibuka di ApexSQL Plan dan dapat dianalisis untuk optimasi kueri.

Perkiraan rencana eksekusi

Melihat paket eksekusi aktual dalam Paket ApexSQL

Untuk melihat rencana pelaksanaan Aktual permintaan, lanjutkan dari langkah ke-2 yang disebutkan sebelumnya, tetapi sekarang, setelah rencana Perkiraan ditampilkan, klik tombol "Aktual" dari bilah pita utama dalam Paket ApexSQL.

klik tombol "Sebenarnya" dari bilah pita utama

Setelah tombol "Aktual" diklik, rencana eksekusi Aktual akan ditampilkan dengan pratinjau terperinci dari parameter biaya bersama dengan data rencana eksekusi lainnya.

Rencana eksekusi aktual

Informasi lebih lanjut tentang melihat rencana eksekusi dapat ditemukan dengan mengikuti tautan ini .


14

Alat favorit saya untuk mendapatkan dan menganalisis secara mendalam rencana pelaksanaan kueri adalah SQL Sentry Plan Explorer . Ini jauh lebih ramah pengguna, nyaman dan komprehensif untuk analisis detail dan visualisasi rencana eksekusi daripada SSMS.

Berikut ini contoh cuplikan layar bagi Anda untuk memiliki gagasan tentang fungsionalitas apa yang ditawarkan oleh alat ini:

Tangkapan layar jendela SQL Sentry Plan Explorer

Ini hanya salah satu tampilan yang tersedia di alat. Perhatikan serangkaian tab di bagian bawah jendela aplikasi, yang memungkinkan Anda mendapatkan berbagai jenis representasi rencana eksekusi dan juga informasi tambahan yang berguna.

Selain itu, saya belum melihat adanya batasan edisi gratis yang mencegah penggunaannya setiap hari atau memaksa Anda untuk membeli versi Pro pada akhirnya. Jadi, jika Anda lebih suka menggunakan edisi gratis, tidak ada yang melarang Anda melakukannya.

UPDATE: (Terima kasih kepada Martin Smith ) Plan Explorer sekarang gratis! Lihat http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view untuk detailnya.


1
Siapa yang berbicara tentang alat pihak ketiga?
basher

12
@ Basher: OP tidak membatasi sarana dengan alat MS atau yang lainnya. Jadi apa yang membuat Anda berpikir jawaban yang melibatkan alat pihak ketiga adalah yang tidak pantas?
Alexander Abakumov

3
Hanya bercanda dengan bagaimana Anda menyusun awal jawaban Anda Speaking of third-party toolsketika tidak ada yang menyebutkan alat pihak ketiga.
basher

4
@basher: Oh, tangkapan bagus! Terima kasih! Saya telah menulis ulang jawaban saya. Silakan memberikan umpan balik dan / atau meningkatkannya jika Anda mau.
Alexander Abakumov


7

Paket kueri dapat diperoleh dari sesi Acara yang diperluas melalui query_post_execution_showplanacara tersebut. Inilah contoh sesi XEvent:

/*
    Generated via "Query Detail Tracking" template.
*/
CREATE EVENT SESSION [GetExecutionPlan] ON SERVER 
ADD EVENT sqlserver.query_post_execution_showplan(
    ACTION(package0.event_sequence,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)),

/* Remove any of the following events (or include additional events) as desired. */
ADD EVENT sqlserver.error_reported(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.module_end(SET collect_statement=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.rpc_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sp_statement_completed(SET collect_object_name=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_batch_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))) 
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO

Setelah Anda membuat sesi, (dalam SSMS) pergi ke Object Explorer dan mempelajari Manajemen | Acara yang Diperpanjang | Sesi. Klik kanan sesi "GetExecutionPlan" dan mulai saja. Klik kanan lagi dan pilih "Tonton Data Langsung".

Selanjutnya, buka jendela permintaan baru dan jalankan satu atau lebih permintaan. Inilah satu untuk AdventureWorks:

USE AdventureWorks;
GO

SELECT p.Name AS ProductName, 
    NonDiscountSales = (OrderQty * UnitPrice),
    Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
FROM Production.Product AS p 
INNER JOIN Sales.SalesOrderDetail AS sod
    ON p.ProductID = sod.ProductID 
ORDER BY ProductName DESC;
GO

Setelah beberapa saat, Anda akan melihat beberapa hasil di tab "GetExecutionPlan: Live Data". Klik salah satu peristiwa query_post_execution_showplan di kisi, dan kemudian klik tab "Rencana Kueri" di bawah kisi. Seharusnya terlihat seperti ini:

masukkan deskripsi gambar di sini

EDIT : Kode XEvent dan tangkapan layar dihasilkan dari SQL / SSMS 2012 w / SP2. Jika Anda menggunakan SQL 2008 / R2, Anda mungkin dapat mengubah skrip untuk membuatnya berjalan. Tetapi versi itu tidak memiliki GUI, jadi Anda harus mengekstrak XML showplan, menyimpannya sebagai file * .sqlplan dan membukanya di SSMS. Itu merepotkan. XEvents tidak ada di SQL 2005 atau sebelumnya. Jadi, jika Anda tidak menggunakan SQL 2012 atau lebih baru, saya akan sangat menyarankan salah satu jawaban lain yang diposting di sini.


5

Mulai dari SQL Server 2016+, fitur Query Store diperkenalkan untuk memantau kinerja. Ini memberikan wawasan tentang pilihan dan kinerja rencana kueri. Ini bukan pengganti lengkap jejak atau peristiwa yang diperpanjang, tetapi karena ini berkembang dari versi ke versi, kita mungkin mendapatkan toko permintaan berfungsi penuh di rilis mendatang dari SQL Server. Aliran utama dari Query Store

  1. SQL Server komponen yang ada berinteraksi dengan toko kueri dengan memanfaatkan Manajer Toko Kueri.
  2. Manajer Toko Kueri menentukan Toko mana yang harus digunakan dan kemudian meneruskan eksekusi ke toko itu (Rencana atau Runtime Stats atau Query Wait Stats)
    • Plan Store - Menahan informasi rencana eksekusi
    • Runtime Stats Store - Tetap menggunakan informasi statistik eksekusi
    • Query Wait Stats Store - Informasi statistik tunggu yang bertahan.
  3. Paket Plan, Runtime Stats dan Wait store menggunakan Query Store sebagai ekstensi ke SQL Server.

masukkan deskripsi gambar di sini

  1. Mengaktifkan Query Store : Query Store bekerja di level database di server.

    • Query Store tidak aktif untuk database baru secara default.
    • Anda tidak dapat mengaktifkan toko permintaan untuk master atau tempdbdatabase.
    • DMV tersedia

      sys.database_query_store_options (Transact-SQL)

  2. Kumpulkan Informasi di Query Store : Kami mengumpulkan semua informasi yang tersedia dari tiga toko menggunakan Query Store DMV (Tampilan Manajemen Data).

CATATAN: Query Wait Stats Store hanya tersedia di SQL Server 2017+


4

Seperti dengan SQL Server Management Studio (sudah dijelaskan), dimungkinkan juga dengan Datagrip seperti yang dijelaskan di sini .

  1. Klik kanan pernyataan SQL, dan pilih Jelaskan paket.
  2. Di panel Output, klik Paket.
  3. Secara default, Anda melihat representasi pohon kueri. Untuk melihat rencana kueri, klik ikon Tampilkan Visualisasi, atau tekan Ctrl + Shift + Alt + U

3

Inilah satu hal penting yang perlu diketahui selain semua yang dikatakan sebelumnya.

Paket kueri seringkali terlalu rumit untuk diwakili oleh tipe kolom XML bawaan yang memiliki batasan 127 level elemen bersarang. Itulah salah satu alasan mengapa sys.dm_exec_query_plan dapat mengembalikan NULLatau bahkan melemparkan kesalahan dalam versi MS SQL sebelumnya, jadi umumnya lebih aman menggunakan sys.dm_exec_text_query_plan sebagai gantinya. Yang terakhir ini juga memiliki fitur bonus yang berguna untuk memilih rencana untuk pernyataan tertentu daripada keseluruhan kumpulan. Berikut cara Anda menggunakannya untuk melihat paket pernyataan yang sedang berjalan:

SELECT p.query_plan
FROM sys.dm_exec_requests AS r
OUTER APPLY sys.dm_exec_text_query_plan(
                r.plan_handle,
                r.statement_start_offset,
                r.statement_end_offset) AS p

Namun kolom teks dalam tabel yang dihasilkan tidak terlalu berguna dibandingkan dengan kolom XML. Untuk dapat mengklik hasil yang akan dibuka di tab terpisah sebagai diagram, tanpa harus menyimpan kontennya ke file, Anda dapat menggunakan sedikit trik (ingat Anda tidak bisa hanya menggunakan CAST(... AS XML)), meskipun ini hanya akan bekerja untuk satu baris:

SELECT Tag = 1, Parent = NULL, [ShowPlanXML!1!!XMLTEXT] = query_plan
FROM sys.dm_exec_text_query_plan(
                -- set these variables or copy values
                -- from the results of the above query
                @plan_handle,
                @statement_start_offset,
                @statement_end_offset)
FOR XML EXPLICIT

3

Anda juga dapat melakukannya melalui PowerShell menggunakan SET STATISTICS XML ON untuk mendapatkan rencana yang sebenarnya. Saya telah menulisnya sehingga menggabungkan rencana multi-pernyataan menjadi satu rencana;

    ########## BEGIN : SCRIPT VARIABLES #####################
    [string]$server = '.\MySQLServer'
    [string]$database = 'MyDatabase'
    [string]$sqlCommand = 'EXEC sp_ExampleSproc'
    [string]$XMLOutputFileName = 'sp_ExampleSproc'
    [string]$XMLOutputPath = 'C:\SQLDumps\ActualPlans\'
    ########## END   : SCRIPT VARIABLES #####################

    #Set up connection
    $connectionString = "Persist Security Info=False;Integrated Security=true;Connection Timeout=0;Initial Catalog=$database;Server=$server"
    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)

    #Set up commands
    $command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
    $command.CommandTimeout = 0
    $commandXMLActPlanOn = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML ON",$connection)
    $commandXMLActPlanOff = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML OFF",$connection)

    $connection.Open()

    #Enable session XML plan
    $result = $commandXMLActPlanOn.ExecuteNonQuery()

    #Execute SP and return resultsets into a dataset
    $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
    $dataset = New-Object System.Data.DataSet
    $adapter.Fill($dataSet) | Out-Null

    #Set up output file name and path
    [string]$fileNameDateStamp = get-date -f yyyyMMdd_HHmmss
    [string]$XMLOutputFilePath = "$XMLOutputPath$XMLOutputFileName`_$fileNameDateStamp.sqlplan"

    #Pull XML plans out of dataset and merge into one multi-statement plan
    [int]$cntr = 1
    ForEach($table in $dataset.Tables)
    {
            if($table.Columns[0].ColumnName -eq "Microsoft SQL Server 2005 XML Showplan")
            {

                [string]$fullXMLPlan = $Table.rows[0]."Microsoft SQL Server 2005 XML Showplan"

                if($cntr -eq 1)
                    {

                    [regex]$rx = "\<ShowPlanXML xmlns\=.{1,}\<Statements\>"
                    [string]$startXMLPlan = $rx.Match($fullXMLPlan).Value
                    [regex]$rx = "\<\/Statements\>.{1,}\<\/ShowPlanXML\>"
                    [string]$endXMLPlan = $rx.Match($fullXMLPlan).Value

                    $startXMLPlan | out-file -Append -FilePath $XMLOutputFilePath

                    }

                [regex]$rx = "\<StmtSimple.{1,}\<\/StmtSimple\>"
                [string]$bodyXMLPlan = $rx.Match($fullXMLPlan).Value

                $bodyXMLPlan | out-file -Append -FilePath $XMLOutputFilePath

                $cntr += 1
            } 
    }

    $endXMLPlan | out-file -Append -FilePath $XMLOutputFilePath

    #Disable session XML plan
    $result = $commandXMLActPlanOff.ExecuteNonQuery()

    $connection.Close()

2

Seperti yang saya jelaskan di artikel ini , ada dua jenis rencana eksekusi yang bisa Anda dapatkan ketika menggunakan SQL Server.

Perkiraan rencana eksekusi

Perkiraan rencana eksekusi dihasilkan oleh Pengoptimal tanpa menjalankan kueri SQL.

Untuk mendapatkan perkiraan rencana eksekusi, Anda harus mengaktifkan SHOWPLAN_ALLpengaturan sebelum mengeksekusi kueri.

SET SHOWPLAN_ALL ON

Sekarang, ketika menjalankan query SQL berikut:

SELECT p.id
FROM post p
WHERE EXISTS (
  SELECT 1
  FROM post_comment pc
  WHERE
    pc.post_id = p.id AND
    pc.review = 'Bingo'
)
ORDER BY p.title
OFFSET 20 ROWS
FETCH NEXT 10 ROWS ONLY

SQL Server akan menghasilkan estimasi rencana eksekusi berikut:

| NodeId | Parent | LogicalOp            | EstimateRows | EstimateIO  | EstimateCPU | AvgRowSize | TotalSubtreeCost | EstimateExecutions |
|--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|--------------------|
| 1      | 0      | NULL                 | 10           | NULL        | NULL        | NULL       | 0.03374284       | NULL               |
| 2      | 1      | Top                  | 10           | 0           | 3.00E-06    | 15         | 0.03374284       | 1                  |
| 4      | 2      | Distinct Sort        | 30           | 0.01126126  | 0.000504114 | 146        | 0.03373984       | 1                  |
| 5      | 4      | Inner Join           | 46.698       | 0           | 0.00017974  | 146        | 0.02197446       | 1                  |
| 6      | 5      | Clustered Index Scan | 43           | 0.004606482 | 0.0007543   | 31         | 0.005360782      | 1                  |
| 7      | 5      | Clustered Index Seek | 1            | 0.003125    | 0.0001581   | 146        | 0.0161733        | 43                 |

Setelah menjalankan kueri, kami tertarik untuk mendapatkan rencana eksekusi yang diperkirakan, Anda harus menonaktifkannya SHOWPLAN_ALLkarena, jika tidak, sesi database saat ini hanya akan menghasilkan estimasi rencana eksekusi alih-alih mengeksekusi query SQL yang disediakan.

SET SHOWPLAN_ALL OFF

Perkiraan paket SQL Server Management Studio

Dalam aplikasi SQL Server Management Studio, Anda dapat dengan mudah mendapatkan estimasi rencana eksekusi untuk setiap permintaan SQL dengan menekan CTRL+Lpintasan kunci.

masukkan deskripsi gambar di sini

Rencana eksekusi aktual

Paket eksekusi SQL aktual dihasilkan oleh Pengoptimal saat menjalankan kueri SQL. Jika statistik tabel database akurat, rencana aktual seharusnya tidak berbeda secara signifikan dari yang diperkirakan.

Untuk mendapatkan rencana eksekusi aktual pada SQL Server, Anda harus mengaktifkan STATISTICS IO, TIME, PROFILEpengaturan, seperti yang diilustrasikan oleh perintah SQL berikut:

SET STATISTICS IO, TIME, PROFILE ON

Sekarang, ketika menjalankan kueri sebelumnya, SQL Server akan menghasilkan rencana eksekusi berikut:

| Rows | Executes | NodeId | Parent | LogicalOp            | EstimateRows | EstimateIO  | EstimateCPU | AvgRowSize | TotalSubtreeCost |
|------|----------|--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|
| 10   | 1        | 1      | 0      | NULL                 | 10           | NULL        | NULL        | NULL       | 0.03338978       |
| 10   | 1        | 2      | 1      | Top                  | 1.00E+01     | 0           | 3.00E-06    | 15         | 0.03338978       |
| 30   | 1        | 4      | 2      | Distinct Sort        | 30           | 0.01126126  | 0.000478783 | 146        | 0.03338679       |
| 41   | 1        | 5      | 4      | Inner Join           | 44.362       | 0           | 0.00017138  | 146        | 0.02164674       |
| 41   | 1        | 6      | 5      | Clustered Index Scan | 41           | 0.004606482 | 0.0007521   | 31         | 0.005358581      |
| 41   | 41       | 7      | 5      | Clustered Index Seek | 1            | 0.003125    | 0.0001581   | 146        | 0.0158571        |

SQL Server parse and compile time:
   CPU time = 8 ms, elapsed time = 8 ms.

(10 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'post'. Scan count 0, logical reads 116, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'post_comment'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(6 row(s) affected)

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 1 ms.

Setelah menjalankan kueri, kami tertarik untuk mendapatkan paket eksekusi yang sebenarnya, Anda perlu menonaktifkan STATISTICS IO, TIME, PROFILE ONpengaturan seperti ini:

SET STATISTICS IO, TIME, PROFILE OFF

Rencana aktual SQL Server Management Studio

Dalam aplikasi SQL Server Management Studio, Anda dapat dengan mudah mendapatkan estimasi rencana eksekusi untuk setiap permintaan SQL dengan menekan CTRL+Mpintasan kunci.

masukkan deskripsi gambar di sini

Untuk detail lebih lanjut tentang mendapatkan rencana eksekusi ketika menggunakan SQL Server, lihat artikel ini .


0

Menjelaskan rencana eksekusi bisa sangat rinci dan memakan waktu yang cukup lama, tetapi dalam ringkasan jika Anda menggunakan 'jelaskan' sebelum permintaan, itu akan memberi Anda banyak info termasuk bagian mana yang dieksekusi terlebih dahulu. jika Anda ingin membaca sedikit lebih detail tentang ini, saya menyusun sebuah blog kecil tentang ini yang mengarahkan Anda juga ke referensi yang tepat. https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.