SQL Server'da bir Sorgu Yürütme Planı nasıl edinirim?


338

Microsoft SQL Server'da bir sorgu / saklı yordam için bir sorgu yürütme planı nasıl alabilirim?


2
SQL Server Management Studio'daki Yürütme Planı sekmesini nasıl kapatabilirim?
Paul McCarthy

2
@Paul Bunun için Ctrl + R tuşlarına basabilirsiniz. Mesajlar ve yürütme planı da dahil olmak üzere tüm sonuçlar bölümünü kapatır.
Nisarg

Yanıtlar:


501

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.

Yöntem 1 - SQL Server Management Studio'yu kullanma

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 .

Eylem Yürütme Planı menü öğesini dahil et

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.

Yürütme Planının Ekran Görüntüsü

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.

Yöntem 2 - SHOWPLAN seçeneklerini kullanma

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

Yürütme planı biçimlerinin karşılaştırılması

Güçlü bir tercihiniz olmadıkça, tavsiyem STATISTICS XMLseç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üler
  • SHOWPLAN_ALL - Sorguyu yürütmeden maliyet tahminleri içeren metin tabanlı bir tahmini yürütme planı görüntüler
  • SHOWPLAN_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.

Yöntem 3 - SQL Server Profiler kullanma

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!

  1. SQL Server Profiler'ı açın ve izlemeyi kaydetmek istediğiniz veritabanına bağlanan yeni bir izleme oluşturun.
  2. "Etkinlik Seçimi" sekmesi altında "Tüm etkinlikleri göster" i, "Performans" -> "Showplan XML" satırını kontrol edin ve izlemeyi çalıştırın.
  3. Izleme çalışırken, yavaş çalışan sorguyu çalıştırmak için yapmanız gereken her şeyi yapın.
  4. Sorgunun izlemeyi tamamlamasını ve durdurmasını bekleyin.
  5. Izleme kaydetmek için SQL Server Profiler plan xml sağ tıklatın ve planı XML biçiminde dosyaya kaydetmek için "Olay verilerini ayıkla ..." seçin.

Aldığınız plan, SQL Server Management Studio'daki "Gerçek Yürütme Planını Ekle" seçeneğine eşdeğerdir.

Yöntem 4 - Sorgu önbelleğini inceleme

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.

Notlar:

Ç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.

"fiili" ve "tahmini" yürütme planları

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.

Bir sorgu yürütme planını nasıl yorumlayabilirim?

Bu, kendi başına (ücretsiz) bir kitap için yeterince değerli bir konudur .

Ayrıca bakınız:


8
Gelecekteki okuyucular için bir not: koymak SET STATISTICS XML ONsorgusunun 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).
Roimer

2
@MonsterMMORPG yöntem 4'ü kullanabilir ve sonra SEÇABİLİRSİNİZ. Örneğin, <a href=" github.com/StackExchange/dapper-dot-net"> Dapper.net </… > connection.Query <string> ("sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text (plan_handle) ) ÇAPRAZ UYGULAYIN sys.dm_exec_query_plan (plan_handle) METİN NEREDE GİBİ N '% Orijinal Sorgunuz Buraya Gidiyor%' "); % 'Leri sorgunuzun yalnızca bir alt kümesini kullanıyorsanız.
bmarks

2
@ Bir sorgu yürütme planını yorumlamak için bağlandığınız kitabın 2. baskısı 2009'dan kalma. 2016'da hala bu amaç için gerçekten iyi bir kaynak olduğunu söyleyebilir misiniz?
Abdul

3
@Abdul Aynı yazar Grant Fritchey, SQL Server'ın daha yeni sürümlerini kapsayan SQL Server Query Performance Tuning adında daha yeni bir kitaba sahip.
thelem

42

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

Örnek StartCaptureTanım

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

Örnek StopCaptureTanım

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

Microsoft SQL Server Management Studio kullandığınızı varsayarsak

  • İçin Tahmini Sorgu Planı basabilirsiniz Ctrl + L veya aşağıdaki düğmeye.

resim açıklamasını buraya girin

  • İçin Gerçek Sorgu Planı , sen basabilirsiniz Ctrl + M veya sorgu çalıştırmadan önce aşağıdaki düğmeyi.

resim açıklamasını buraya girin

  • İçin Canlı Sorgu Planı (sadece 2016 SSMS), sorguyu çalıştırmadan önce aşağıdaki düğmesini kullanın.

resim açıklamasını buraya girin


15

Ö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

  1. Click Yeni Sorgu SSMS düğmesi ve sorgu metin penceresinde sorgu metnini yapıştırın. Sağ tıklayın ve içerik menüsünden “Tahmini Yürütme Planını Görüntüle” seçeneğini seçin.

SSMS'de yeni Sorgu düğmesi

  1. Yürütme planı diyagramları, sonuçlar bölümünde Yürütme Planı sekmesini gösterecektir. Ardından yürütme planına sağ tıklayın ve içerik menüsünde “ApexSQL Planında Aç” seçeneğini seçin.

Yürütme planı

  1. Tahmini yürütme planı ApexSQL Planında açılacak ve sorgu optimizasyonu için analiz edilebilir.

Tahmini yürütme planı

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.

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.

Gerçek uygulama planı

Yürütme planlarını görüntüleme hakkında daha fazla bilgi bu bağlantıyı izleyerek bulunabilir .


14

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ü:

SQL Sentry Plan Explorer pencere 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.


1
Üçüncü taraf araçlardan kim bahsediyordu?
basher

12
@basher: OP, araçları MS araçlarıyla veya başka bir şekilde sınırlamadı. Peki, üçüncü taraf bir aracı içeren bir cevabın uygunsuz olduğunu düşünmenizi sağlayan şey nedir?
Alexander Abakumov

3
Speaking of third-party toolsKimse üçüncü taraf araçlarından bahsetmediğinde cevabınızın başlangıcını nasıl ifade ettiğinizle şaka yapıyordum .
basher

4
@basher: Oh, güzel yakala! Teşekkür ederim! Cevabımı yeniden yazdım. Lütfen geri bildirimde bulunmaktan ve / veya isterseniz oyunuzu yükseltmekten çekinmeyin.
Alexander Abakumov


7

Sorgu planları, query_post_execution_showplanetkinlik 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:

resim açıklamasını buraya girin

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.


5

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ışı

  1. SQL Server varolan bileşenleri sorgu deposu ile Query Store Manager kullanarak etkileşim.
  2. Sorgu Deposu Yöneticisi hangi Deponun kullanılacağını belirler ve ardından bu depoya yürütmeyi iletir (Plan veya Çalışma Zamanı İstatistikleri veya Sorgu Bekleme İstatistikleri)
    • Plan Mağazası - İcra planı bilgilerinin kalıcılığı
    • Çalışma Zamanı İstatistikleri Mağazası - Yürütme istatistikleri bilgilerinin kalıcı olması
    • Sorgu Bekleme İstatistikleri Mağaza - Kalıcı bekleme istatistik bilgileri.
  3. Plan, Çalışma Zamanı İstatistikleri ve Bekleme deposu, Query Store'u SQL Server'ın bir uzantısı olarak kullanır.

resim açıklamasını buraya girin

  1. Sorgu Deposunu Etkinleştirme : Sorgu Deposu sunucudaki veritabanı düzeyinde çalışır.

    • Sorgu Deposu varsayılan olarak yeni veritabanları için etkin değildir.
    • Ana depo veya tempdbveritabanı için sorgu deposunu etkinleştiremezsiniz .
    • Mevcut DMV

      sys.database_query_store_options (Transact-SQL)

  2. 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


4

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 .

  1. Bir SQL deyimini sağ tıklatın ve Planı açıkla'yı seçin.
  2. Çıktı bölmesinde Planla'yı tıklatın.
  3. 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

3

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

3

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()

2

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ı

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 tahmini planı

SQL Server Management Studio uygulamasında, CTRL+Lanahtar kısayoluna basarak herhangi bir SQL sorgusu için tahmini yürütme planını kolayca alabilirsiniz .

resim açıklamasını buraya girin

Gerçek uygulama planı

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 ONistiyoruz , aşağıdaki gibi ayarları devre dışı bırakmanız gerekir :

SET STATISTICS IO, TIME, PROFILE OFF

SQL Server Management Studio gerçek planı

SQL Server Management Studio uygulamasında, CTRL+Manahtar kısayoluna basarak herhangi bir SQL sorgusu için tahmini yürütme planını kolayca alabilirsiniz .

resim açıklamasını buraya girin

SQL Server kullanırken yürütme planı alma hakkında daha fazla bilgi için bu makaleye göz atın .


0

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.