Microsoft SQL Server'da bir sorgu / saklı yordam için bir sorgu yürütme planı nasıl alabilirim?
Microsoft SQL Server'da bir sorgu / saklı yordam için bir sorgu yürütme planı nasıl alabilirim?
Yanıtlar:
Kullanılacak olanın sizin koşullarınıza bağlı olacağı bir yürütme planı edinmenin birkaç yöntemi vardır. Genellikle bir plan almak için SQL Server Management Studio'yu kullanabilirsiniz, ancak herhangi bir nedenden dolayı sorgunuzu SQL Server Management Studio'da çalıştıramazsanız, SQL Server Profiler aracılığıyla veya teftiş ederek bir plan elde etmenin yararlı olduğunu görebilirsiniz. önbellek.
SQL Server, bir yürütme planı yakalamayı çok kolaylaştıran birkaç düzgün özellik ile birlikte gelir, sadece "Gerçek Yürütme Planını Dahil Et" menü öğesinin ("Sorgu" menüsü altında bulunur) işaretlendiğinden emin olun ve sorgunuzu normal şekilde çalıştırın .
Saklı bir yordamdaki ifadeler için yürütme planı elde etmeye çalışıyorsanız, saklı yordamı, aşağıdaki gibi yürütmelisiniz:
exec p_Example 42
Sorgunuz tamamlandığında, sonuçlar bölmesinde "Yürütme planı" başlıklı ek bir sekme görmeniz gerekir. Çok sayıda ifade çalıştırdıysanız, bu sekmede birçok plan görebilirsiniz.
Buradan SQL Server Management Studio'daki yürütme planını inceleyebilir veya planı sağ tıklayıp planı XML biçiminde bir dosyaya kaydetmek için "Yürütme Planını Farklı Kaydet ..." seçeneğini belirleyebilirsiniz.
Bu yöntem (aslında SQL Server Management Studio dahili olarak ne yapar) yöntem 1 çok benzer, ancak ben tamlık için dahil veya SQL Server Management Studio yoksa.
Sorgunuzu çalıştırmadan önce aşağıdaki ifadelerden birini çalıştırın . İfade, toplu işteki tek ifade olmalıdır, yani aynı anda başka bir ifade çalıştıramazsınız:
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
Bunlar bağlantı seçenekleridir ve bu nedenle bağlantı başına yalnızca bir kez çalıştırmanız gerekir. Bu noktadan sonra, çalıştırılan tüm ifadeler , yürütme planınızı istenen biçimde içeren ek bir sonuç kümesiyle birlikte gönderilir - normalde planı görmek için sorgunuzu çalıştırmanız yeterlidir.
İşiniz bittiğinde bu seçeneği aşağıdaki ifadeyle kapatabilirsiniz:
SET <<option>> OFF
Güçlü bir tercihiniz olmadıkça, tavsiyem STATISTICS XML
seçeneği kullanmaktır . Bu seçenek, SQL Server Management Studio'daki "Gerçek Yürütme Planını Ekle" seçeneğine eşdeğerdir ve en çok bilgiyi en uygun biçimde sağlar.
SHOWPLAN_TEXT
- Sorguyu çalıştırmadan temel bir metin tabanlı tahmini yürütme planı görüntülerSHOWPLAN_ALL
- Sorguyu yürütmeden maliyet tahminleri içeren metin tabanlı bir tahmini yürütme planı görüntülerSHOWPLAN_XML
- Sorguyu yürütmeden maliyet tahminleriyle XML tabanlı bir tahmini yürütme planı görüntüler. Bu, SQL Server Management Studio'daki "Tahmini Yürütme Planını Görüntüle ..." seçeneğine eşdeğerdir.STATISTICS PROFILE
- Sorguyu yürütür ve metin tabanlı gerçek yürütme planını görüntüler.STATISTICS XML
- Sorguyu yürütür ve XML tabanlı gerçek yürütme planını görüntüler. Bu, SQL Server Management Studio'daki "Gerçek Yürütme Planını Ekle" seçeneğine eşdeğerdir.Sorgunuzu doğrudan çalıştıramazsanız (veya doğrudan yürüttüğünüzde sorgunuz yavaş çalışmazsa - sorgunun bir planının kötü performans göstermesini istediğimizi unutmayın), bir SQL Server Profiler izlemesi kullanarak bir plan yakalayabilirsiniz. Fikir, "Showplan" olaylarından birini yakalayan bir izleme çalışırken sorgunuzu çalıştırmaktır.
Not yüke bağlı o olabilir bir üretim ortamında bu yöntemi kullanmak, ancak belli ki dikkatli kullanmalıdır. SQL Server profil oluşturma mekanizmaları veritabanı üzerindeki etkiyi en aza indirecek şekilde tasarlanmıştır, ancak bu herhangi bir performans etkisi olmayacağı anlamına gelmez . Veritabanınız yoğun kullanımdaysa, izlemenizde doğru planı filtrelemek ve tanımlamakta sorun yaşayabilirsiniz. Değerli veritabanlarında bunu yapmaktan memnun olup olmadıklarını görmek için DBA'nıza açıkça bakmalısınız!
Aldığınız plan, SQL Server Management Studio'daki "Gerçek Yürütme Planını Ekle" seçeneğine eşdeğerdir.
Sorgunuzu doğrudan çalıştıramazsanız ve aynı zamanda bir profil oluşturucu yakalayamazsanız, SQL sorgu planı önbelleğini inceleyerek yine de tahmini bir plan elde edebilirsiniz.
SQL Server DMV'lerini sorgulayarak plan önbelleğini inceleriz . Aşağıda, önbelleğe alınmış tüm sorgu planlarını (xml olarak) SQL metinleriyle birlikte listeleyecek temel bir sorgu yer almaktadır. Çoğu veritabanında, sonuçları yalnızca ilgilendiğiniz planlara göre filtrelemek için ek filtreleme maddeleri eklemeniz gerekir.
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)
Bu sorguyu yürütün ve planı yeni bir pencerede açmak için plan XML'ini tıklayın - sağ tıklayın ve planı XML biçiminde dosyaya kaydetmek için "Yürütme planını farklı kaydet ..." seçeneğini seçin.
Çok fazla faktör bulunduğundan (tablo ve dizin şemasından depolanan verilere ve tablo istatistiklerine kadar) her zaman ilgilendiğiniz veritabanından bir yürütme planı (normalde bir performansla karşılaşan) elde etmeye çalışmalısınız. sorun).
Şifrelenmiş saklı yordamlar için bir yürütme planı yakalayamazsınız.
Bir fiili yürütme planı bir oysa SQL Server aslında sorguyu çalıştırır biridir tahmini yürütme planı SQL Server ne dışarı çalışır ediyorum Sorgu yürütülürken olmadan. Mantıksal olarak eşdeğer olsa da, gerçek bir yürütme planı, sorguyu yürütürken gerçekte ne olduğuna dair ek ayrıntılar ve istatistikler içerdiğinden çok daha kullanışlıdır. Bu, SQL Server tahminlerinin kapalı olduğu (örneğin istatistiklerin güncel olmadığı zamanlar) sorunları teşhis ederken önemlidir.
Bu, kendi başına (ücretsiz) bir kitap için yeterince değerli bir konudur .
SET STATISTICS XML ON
sorgusunun başlangıcını karınca ve SET STATISTICS XML OFF|ON
çevresinde sen yok planı çıkışta gösterilmesine istiyorum: Sorgu bir kez yinelenir (WHILE) İstemediğiniz / ihtiyaç içerdiğinde ben bunu yararlı buldu (aksi takdirde SQL SERVER'in bunu göstermesi çok ağır ve uzun olur).
Daha önce gönderilen kapsamlı cevaba ek olarak, bilgi çıkarmak için yürütme planına programlı olarak erişebilmek yararlıdır. Bunun için örnek kod aşağıdadır.
DECLARE @TraceID INT
EXEC StartCapture @@SPID, @TraceID OUTPUT
EXEC sp_help 'sys.objects' /*<-- Call your stored proc of interest here.*/
EXEC StopCapture @TraceID
StartCapture
TanımCREATE 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
TanımCREATE 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
Microsoft SQL Server Management Studio kullandığınızı varsayarsak
Önceki yanıtlarda açıklanan yöntemlerin yanı sıra, ücretsiz yürütme planı görüntüleyicisi ve sorgu optimizasyon aracı ApexSQL Planı'nı (yakın zamanda karşılaştığım) da kullanabilirsiniz.
ApexSQL Planını SQL Server Management Studio'ya kurabilir ve entegre edebilirsiniz, böylece yürütme planları doğrudan SSMS'den görüntülenebilir.
ApexSQL Planında Tahmini yürütme planlarını görüntüleme
ApexSQL Planında gerçek yürütme planlarını görüntüleme
Bir sorgunun Gerçek yürütme planını görüntülemek için daha önce belirtilen 2. adımdan devam edin, ancak şimdi Tahmini plan gösterildikten sonra ApexSQL Planındaki ana şerit çubuğundan “Gerçek” düğmesini tıklayın.
“Gerçek” düğmesine tıklandığında, Gerçek yürütme planı, diğer yürütme planı verileriyle birlikte maliyet parametrelerinin ayrıntılı önizlemesiyle birlikte gösterilir.
Yürütme planlarını görüntüleme hakkında daha fazla bilgi bu bağlantıyı izleyerek bulunabilir .
Sorgu yürütme planlarını elde etmek ve derinlemesine analiz etmek için en sevdiğim araç SQL Sentry Plan Explorer . Uygulama planlarının detay analizi ve görselleştirilmesi için SSMS'den çok daha kullanıcı dostu, kullanışlı ve kapsamlı.
Araç tarafından hangi işlevlerin sunulduğu hakkında bir fikriniz olması için örnek bir ekran görüntüsü:
Araçta bulunan görünümlerden yalnızca biri. Uygulama penceresinin alt kısmında, yürütme planı temsilinizin farklı türlerini ve kullanışlı ek bilgileri almanıza olanak tanıyan bir dizi sekmeye dikkat edin.
Ayrıca, ücretsiz sürümünün günlük olarak kullanılmasını önleyen veya sizi Pro sürümünü sonunda satın almaya zorlayan herhangi bir sınırlama fark etmedim. Yani, ücretsiz sürüme bağlı kalmayı tercih ederseniz, hiçbir şey bunu yapmanızı engellemez.
GÜNCELLEME: ( Martin Smith sayesinde ) Plan Explorer artık ücretsiz! Ayrıntılar için http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view adresine bakın.
Speaking of third-party tools
Kimse üçüncü taraf araçlarından bahsetmediğinde cevabınızın başlangıcını nasıl ifade ettiğinizle şaka yapıyordum .
Sorgu planları, query_post_execution_showplan
etkinlik yoluyla bir Genişletilmiş Etkinlikler oturumundan edinilebilir . İşte örnek bir XEvent oturumu:
/*
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
Oturumu oluşturduktan sonra, (SSMS'de) Nesne Gezgini'ne gidin ve Yönetim | Genişletilmiş Etkinlikler | Oturumlar. "GetExecutionPlan" oturumunu sağ tıklatın ve başlatın. Tekrar sağ tıklayın ve "Canlı Verileri İzle" yi seçin.
Ardından, yeni bir sorgu penceresi açın ve bir veya daha fazla sorgu çalıştırın. AdventureWorks için bir tane:
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
Bir veya iki dakika sonra, "GetExecutionPlan: Canlı Veri" sekmesinde bazı sonuçlar görmeniz gerekir. Kılavuzdaki query_post_execution_showplan olaylarından birini tıklatın ve kılavuzun altındaki "Sorgu Planı" sekmesini tıklatın. Buna benzer görünmelidir:
EDIT : XEvent kodu ve ekran görüntüsü SQL / SSMS 2012 w / SP2'den üretildi. SQL 2008 / R2 kullanıyorsanız, sen belki o çalışmasını sağlamak için komut dosyası oynamak mümkün. Ancak bu sürümün GUI'si yoktur, bu nedenle showplan XML'sini ayıklamanız, * .sqlplan dosyası olarak kaydetmeniz ve SSMS'de açmanız gerekir. Bu hantal. XEvents SQL 2005 veya önceki sürümlerinde yoktu. SQL 2012 veya daha yeni bir sürümde değilseniz, burada yayınlanan diğer yanıtlardan birini şiddetle öneririm.
SQL Server 2016+ sürümünden başlayarak, performansı izlemek için Query Store özelliği tanıtıldı. Sorgu planı seçimi ve performansı hakkında fikir verir. İzleme veya genişletilmiş olayların tamamen değiştirilmesi değil, ancak sürümden sürüme dönüştüğü için, SQL Server'ın gelecekteki sürümlerinde tamamen işlevsel bir sorgu deposu alabiliriz. Sorgu Deposu'nun birincil akışı
Sorgu Deposunu Etkinleştirme : Sorgu Deposu sunucudaki veritabanı düzeyinde çalışır.
tempdb
veritabanı için sorgu deposunu etkinleştiremezsiniz .
sys.database_query_store_options
(Transact-SQL)
Sorgu Deposunda Bilgi Toplama : Query Store DMV (Veri Yönetimi Görünümleri) kullanarak mevcut tüm bilgileri üç mağazadan toplarız.
Sorgu Planı Mağazası: Yürütme planı bilgilerinin kalıcı olması ve sorgu derlemesiyle ilgili tüm bilgileri yakalamaktan sorumludur.
sys.query_store_query
(Transact-sql)sys.query_store_plan
(Transact-sql)sys.query_store_query_text
(Transact-sql)
Çalışma Zamanı İstatistikleri Mağazası: Yürütme istatistikleri bilgilerinin kalıcı olması ve muhtemelen en sık güncellenen deposudur. Bu istatistikler sorgu yürütme verilerini temsil eder.
sys.query_store_runtime_stats
(Transact-SQL)
Query Wait Stats Store: Bekleme istatistikleri bilgilerini ısrar ve yakalamak.
sys.query_store_wait_stats
(Transact-SQL)
NOT: Sorgu Bekleme İstatistikleri Mağazası yalnızca SQL Server 2017 ve sonraki sürümlerinde kullanılabilir
SQL Server Management Studio'da olduğu gibi (daha önce açıklanmıştır), burada açıklandığı gibi Datagrip ile de mümkündür .
- Bir SQL deyimini sağ tıklatın ve Planı açıkla'yı seçin.
- Çıktı bölmesinde Planla'yı tıklatın.
- Varsayılan olarak, sorgunun ağaç temsilini görürsünüz. Sorgu planını görmek için Görselleştirmeyi Göster simgesini tıklatın veya Ctrl + Shift + Alt + U tuşlarına basın
Daha önce söylenen her şeye ek olarak bilmeniz gereken önemli bir şey var.
Sorgu planları, 127 iç içe öğenin sınırlama düzeyine sahip yerleşik XML sütun türüyle gösterilemeyecek kadar karmaşıktır . Bu, sys.dm_exec_query_plan'ınNULL
önceki MS SQL sürümlerinde geri dönmesinin veya hatta hata atmasının nedenlerinden biridir , bu nedenle genellikle sys.dm_exec_text_query_plan kullanmak daha güvenlidir . İkincisi ayrıca, toplu işin tamamı yerine belirli bir ifade için bir plan seçme konusunda yararlı bir bonus özelliğine sahiptir . Şu anda çalışan ifadelere ilişkin planları görüntülemek için bunu nasıl kullanacağınız aşağıda açıklanmıştır:
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
Bununla birlikte, sonuçtaki tablodaki metin sütunu bir XML sütununa kıyasla çok kullanışlı değildir. İçeriğini bir dosyaya kaydetmek zorunda kalmadan ayrı bir sekmede açılacak sonucu bir diyagram olarak tıklayabilmek için, küçük bir hile kullanabilirsiniz (sadece kullanamayacağınızı unutmayın CAST(... AS XML)
), ancak bu yalnızca bir tek sıra:
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
Gerçek planı almak için SET STATISTICS XML ON kullanarak powershell ile de yapabilirsiniz. Bunu, çoklu tablo planlarını tek bir planla birleştirecek şekilde yazdım;
########## 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()
Bu makalede açıkladığım gibi , SQL Server kullanırken alabileceğiniz iki yürütme planı türü vardır.
Tahmini yürütme planı, SQL sorgusu çalıştırılmadan Doktor tarafından oluşturulur.
Tahmini yürütme planını almak için SHOWPLAN_ALL
, sorguyu yürütmeden önce ayarı etkinleştirmeniz gerekir .
SHOWPLAN_ALL AÇIK AYARLA
Şimdi, aşağıdaki SQL sorgusunu yürütürken:
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 aşağıdaki tahmini yürütme planını oluşturur:
| 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 |
Sorguyu çalıştırdıktan sonra, tahmini yürütme planını almakla ilgileniyoruz, as'yi devre dışı bırakmanız gerekiyor SHOWPLAN_ALL
, aksi takdirde, geçerli veritabanı oturumu sağlanan SQL sorgularını yürütmek yerine yalnızca tahmini yürütme planı oluşturur.
SET SHOWPLAN_ALL OFF
SQL Server Management Studio uygulamasında, CTRL+L
anahtar kısayoluna basarak herhangi bir SQL sorgusu için tahmini yürütme planını kolayca alabilirsiniz .
Gerçek SQL yürütme planı, SQL sorgusu çalıştırılırken Doktor tarafından oluşturulur. Veritabanı tablosu istatistikleri doğruysa, gerçek plan tahmin edilenden önemli ölçüde farklı olmamalıdır.
SQL Server'da gerçek yürütme planını almak için STATISTICS IO, TIME, PROFILE
, aşağıdaki SQL komutuyla gösterildiği gibi ayarları etkinleştirmeniz gerekir :
SET STATISTICS IO, TIME, PROFILE ON
Şimdi, önceki sorguyu çalıştırırken, SQL Server aşağıdaki yürütme planını oluşturacaktır:
| 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.
Sorguyu çalıştırdıktan sonra, gerçek yürütme planını almak STATISTICS IO, TIME, PROFILE ON
istiyoruz , aşağıdaki gibi ayarları devre dışı bırakmanız gerekir :
SET STATISTICS IO, TIME, PROFILE OFF
SQL Server Management Studio uygulamasında, CTRL+M
anahtar kısayoluna basarak herhangi bir SQL sorgusu için tahmini yürütme planını kolayca alabilirsiniz .
SQL Server kullanırken yürütme planı alma hakkında daha fazla bilgi için bu makaleye göz atın .
Yürütme planını açıklamak çok ayrıntılı olabilir ve bir okuma süresi alır, ancak sorgudan önce 'açıkla' kullanırsanız, ilk olarak hangi bölümlerin ilk önce çalıştırıldığı da dahil olmak üzere çok fazla bilgi vermelidir. bununla ilgili biraz daha ayrıntı okumak isterseniz, sizi doğru referanslara yönlendiren küçük bir blog derledim. https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470