Di Microsoft SQL Server bagaimana saya bisa mendapatkan rencana eksekusi permintaan untuk prosedur query / tersimpan?
Di Microsoft SQL Server bagaimana saya bisa mendapatkan rencana eksekusi permintaan untuk prosedur query / tersimpan?
Jawaban:
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.
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 .
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.
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 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
Kecuali Anda memiliki preferensi yang kuat, rekomendasi saya adalah menggunakan STATISTICS XML
opsi. 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 kueriSHOWPLAN_ALL
- Menampilkan estimasi rencana eksekusi berdasarkan teks dengan estimasi biaya, tanpa mengeksekusi kueriSHOWPLAN_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.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!
Paket yang Anda dapatkan setara dengan opsi "Sertakan Rencana Eksekusi Aktual" di SQL Server Management Studio.
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.
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.
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).
Ini adalah cukup layak topik untuk (gratis) buku dalam dirinya sendiri.
SET STATISTICS XML ON
semut awal kueri, dan SET STATISTICS XML OFF|ON
area 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).
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
StartCapture
DefinisiCREATE 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
StopCapture
DefinisiCREATE 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
Dengan asumsi Anda menggunakan Microsoft SQL Server Management Studio
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
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.
Setelah tombol "Aktual" diklik, rencana eksekusi Aktual akan ditampilkan dengan pratinjau terperinci dari parameter biaya bersama dengan data rencana eksekusi lainnya.
Informasi lebih lanjut tentang melihat rencana eksekusi dapat ditemukan dengan mengikuti tautan ini .
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:
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.
Speaking of third-party tools
ketika tidak ada yang menyebutkan alat pihak ketiga.
Paket kueri dapat diperoleh dari sesi Acara yang diperluas melalui query_post_execution_showplan
acara 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:
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.
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
Mengaktifkan Query Store : Query Store bekerja di level database di server.
tempdb
database.
sys.database_query_store_options
(Transact-SQL)
Kumpulkan Informasi di Query Store : Kami mengumpulkan semua informasi yang tersedia dari tiga toko menggunakan Query Store DMV (Tampilan Manajemen Data).
Query Plan Store: Menahan informasi rencana eksekusi dan bertanggung jawab untuk menangkap semua informasi yang terkait dengan kompilasi permintaan.
sys.query_store_query
(Transact-SQL)sys.query_store_plan
(Transact-SQL)sys.query_store_query_text
(Transact-SQL)
Toko Statistik Runtime: Tetap menggunakan informasi statistik eksekusi dan mungkin merupakan toko yang paling sering diperbarui. Statistik ini mewakili data eksekusi permintaan.
sys.query_store_runtime_stats
(Transact-SQL)
Stats Wait Query Store: Bertahan dan menangkap informasi statistik tunggu.
sys.query_store_wait_stats
(Transact-SQL)
CATATAN: Query Wait Stats Store hanya tersedia di SQL Server 2017+
Seperti dengan SQL Server Management Studio (sudah dijelaskan), dimungkinkan juga dengan Datagrip seperti yang dijelaskan di sini .
- Klik kanan pernyataan SQL, dan pilih Jelaskan paket.
- Di panel Output, klik Paket.
- Secara default, Anda melihat representasi pohon kueri. Untuk melihat rencana kueri, klik ikon Tampilkan Visualisasi, atau tekan Ctrl + Shift + Alt + U
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 NULL
atau 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
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()
Seperti yang saya jelaskan di artikel ini , ada dua jenis rencana eksekusi yang bisa Anda dapatkan ketika menggunakan SQL Server.
Perkiraan rencana eksekusi dihasilkan oleh Pengoptimal tanpa menjalankan kueri SQL.
Untuk mendapatkan perkiraan rencana eksekusi, Anda harus mengaktifkan SHOWPLAN_ALL
pengaturan 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_ALL
karena, jika tidak, sesi database saat ini hanya akan menghasilkan estimasi rencana eksekusi alih-alih mengeksekusi query SQL yang disediakan.
SET SHOWPLAN_ALL OFF
Dalam aplikasi SQL Server Management Studio, Anda dapat dengan mudah mendapatkan estimasi rencana eksekusi untuk setiap permintaan SQL dengan menekan CTRL+L
pintasan kunci.
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, PROFILE
pengaturan, 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 ON
pengaturan seperti ini:
SET STATISTICS IO, TIME, PROFILE OFF
Dalam aplikasi SQL Server Management Studio, Anda dapat dengan mudah mendapatkan estimasi rencana eksekusi untuk setiap permintaan SQL dengan menekan CTRL+M
pintasan kunci.
Untuk detail lebih lanjut tentang mendapatkan rencana eksekusi ketika menggunakan SQL Server, lihat artikel ini .
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