SQL Server hiç bitmemiş gibi görünen sorgularda sorun giderme
Bu makalede, hiçbir zaman tamamlanmamış gibi görünen bir sorgunuz olduğu veya tamamlanmasının birkaç saat veya gün sürebileceği sorun için sorun giderme adımları açıklanmaktadır.
Hiç bitmeyen sorgu nedir?
Bu belge, yürütmeye veya derlemeye devam eden sorgulara, yani CPU'larının artmaya devam etmesine odaklanır. Engellenen veya hiçbir zaman yayımlanmayan bir kaynağı bekleyen sorgular için geçerli değildir (CPU sabit kalır veya çok az değişir).
Önemli
Yürütmeyi tamamlamak için bir sorgu bırakılırsa, sonunda tamamlanır. Yalnızca birkaç saniye veya birkaç gün sürebilir.
Hiçbir zaman bitmeyen terim, sorgu sonunda tamamlandığında sorgunun tamamlanmadığı algısını açıklamak için kullanılır.
Hiç bitmeyen bir sorguyu tanımlama
Sorguların sürekli olarak yürütülüyor mu yoksa bir performans sorununa mı takılı kaldığını belirlemek için şu adımları izleyin:
Aşağıdaki sorguyu çalıştırın:
DECLARE @cntr int = 0 WHILE (@cntr < 3) BEGIN SELECT TOP 10 s.session_id, r.status, r.wait_time, r.wait_type, r.wait_resource, r.cpu_time, r.logical_reads, r.reads, r.writes, r.total_elapsed_time / (1000 * 60) 'Elaps M', SUBSTRING(st.TEXT, (r.statement_start_offset / 2) + 1, ((CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(st.TEXT) ELSE r.statement_end_offset END - r.statement_start_offset) / 2) + 1) AS statement_text, COALESCE(QUOTENAME(DB_NAME(st.dbid)) + N'.' + QUOTENAME(OBJECT_SCHEMA_NAME(st.objectid, st.dbid)) + N'.' + QUOTENAME(OBJECT_NAME(st.objectid, st.dbid)), '') AS command_text, r.command, s.login_name, s.host_name, s.program_name, s.last_request_end_time, s.login_time, r.open_transaction_count, atrn.name as transaction_name, atrn.transaction_id, atrn.transaction_state FROM sys.dm_exec_sessions AS s JOIN sys.dm_exec_requests AS r ON r.session_id = s.session_id CROSS APPLY sys.Dm_exec_sql_text(r.sql_handle) AS st LEFT JOIN (sys.dm_tran_session_transactions AS stran JOIN sys.dm_tran_active_transactions AS atrn ON stran.transaction_id = atrn.transaction_id) ON stran.session_id =s.session_id WHERE r.session_id != @@SPID ORDER BY r.cpu_time DESC SET @cntr = @cntr + 1 WAITFOR DELAY '00:00:05' END
Örnek çıkışı denetleyin.
Bu makaledeki sorun giderme adımları, cpu'nun geçen süreyle orantılı olarak önemli bekleme süreleri olmadan arttığı aşağıdakine benzer bir çıkış fark ettiğinizde özellikle geçerlidir. Bazı CPU'ya bağlı T-SQL istekleri hiç mantıksal okuma yapmayabileceği için (örneğin hesaplamalar veya
WHILE
döngü gerçekleştirme) içindeki değişikliklerinlogical_reads
bu durumda uygun olmadığını unutmayın.Session_id Durum cpu_time logical_reads wait_time wait_type 56 Çalışan 7038 101000 0 NULL 56 çalıştırılabilir 12040 301000 0 NULL 56 Çalışan 17020 523000 0 NULL Cpu'nun çok az değişmediği veya çok az değişmediği ve oturumun bir kaynakta beklediği aşağıdakine benzer bir bekleme senaryosu gözlemlerseniz bu makale geçerli değildir.
Session_id Durum cpu_time logical_reads wait_time wait_type 56 Askıya 0 3 8312 LCK_M_U 56 Askıya 0 3 13318 LCK_M_U 56 Askıya 0 5 18331 LCK_M_U
Daha fazla bilgi için bkz. Beklemeleri veya performans sorunlarını tanılama.
Uzun derleme süresi
Nadir durumlarda CPU'nun zaman içinde sürekli arttığını ancak bunun sorgu yürütme tarafından yönlendirilmediğini gözlemleyebilirsiniz. Bunun yerine, aşırı uzun bir derleme (sorguyu ayrıştırma ve derleme) tarafından yönlendirilebilir. Bu gibi durumlarda , transaction_name çıkış sütununu denetleyin ve değerini sqlsource_transform
arayın. Bu işlem adı bir derlemeyi gösterir.
Tanılama verilerini toplama
- SQL Server 2008 - SQL Server 2014 (SP2 öncesi)
- SQL Server 2014 (SP2 sonrasında) ve SQL Server 2016 (SP1 öncesinde)
- SQL Server 2016 (SP1 sonrasında) ve SQL Server 2017
- SQL Server 2019 ve sonraki sürümleri
SQL Server Management Studio (SSMS) kullanarak tanılama verilerini toplamak için şu adımları izleyin:
Tahmini sorgu yürütme planı XML'sini yakalayın.
Yavaşlığın nereden gelebileceğine dair belirgin göstergeler olup olmadığını görmek için sorgu planını gözden geçirin. Tipik örnekler şunlardır:
- Tablo veya dizin taramaları (tahmini satırlara bakın).
- Büyük bir dış tablo veri kümesi tarafından yönlendirilen iç içe döngüler.
- Döngünün iç tarafında büyük bir dal bulunan iç içe döngüler.
- Tablo biriktiricileri.
SELECT
Listedeki her satırın işlenmesi uzun süren işlevler.
Sorgu herhangi bir zamanda hızlı çalışıyorsa, karşılaştırmak için "hızlı" yürütmeleri Gerçek XML Yürütme Planı'nı yakalayabilirsiniz.
Toplanan planları gözden geçirme yöntemi
Bu bölümde toplanan verilerin nasıl gözden geçirileceği gösterilmektedir. SQL Server 2016 SP1 ve sonraki derlemelerde ve sürümlerde toplanan birden çok XML sorgu planını (*.sqlplan uzantısını kullanarak) kullanır.
Yürütme planlarını karşılaştırmak için şu adımları izleyin:
Daha önce kaydedilmiş bir sorgu yürütme planı dosyasını (.sqlplan) açın.
Yürütme planının boş bir alanına sağ tıklayın ve Showplan'ı Karşılaştır'ı seçin.
Karşılaştırmak istediğiniz ikinci sorgu planı dosyasını seçin.
İşleçler arasında akan çok sayıda satırı gösteren kalın okları arayın. Ardından, ok öncesinde veya sonrasında işleci seçin ve iki plandaki gerçek satır sayısını karşılaştırın.
En büyük satır akışının aynı işleçlerde olup olmadığını görmek için ikinci ve üçüncü planları karşılaştırın.
İşte bir örnek:
Çözüm
Sorguda kullanılan tablolar için istatistiklerin güncelleştirildiğinden emin olun.
Sorgu planında eksik bir dizin önerisi arayın ve herhangi birini uygulayın.
Sorguyu basitleştirmek amacıyla yeniden yazın:
- Önceden işlenen verileri azaltmak için daha fazla seçmeli
WHERE
koşul kullanın. - Parçala.
- Geçici tablolarda bazı bölümleri seçin ve daha sonra birleştirin.
- İyileştirici satır hedefi nedeniyle çok uzun süre çalışan sorgularda ,
EXISTS
veFAST
(T-SQL) öğelerini kaldırınTOP
. Alternatif olarak ipucunuDISABLE_OPTIMIZER_ROWGOAL
kullanabilirsiniz. Daha fazla bilgi için bkz. Satır Goals Gone Rogue. - Deyimleri tek bir büyük sorguda birleştirdikleri durumlarda Ortak Tablo İfadeleri (CTE) kullanmaktan kaçının.
- Önceden işlenen verileri azaltmak için daha fazla seçmeli
Daha iyi bir plan oluşturmak için sorgu ipuçlarını kullanmayı deneyin:
HASH JOIN
veyaMERGE JOIN
ipucuFORCE ORDER
IpucuFORCESEEK
IpucuRECOMPILE
- Zorlayabileceğiniz hızlı bir sorgu planınız varsa KULLAN
PLAN N'<xml_plan>'
Böyle bir plan varsa ve SQL Server sürümünüz Sorgu Deposu'yu destekliyorsa, iyi bilinen bir planı zorlamak için Sorgu Deposu'yu (QDS) kullanın.
Beklemeleri veya performans sorunlarını tanılama
Bu bölüm, sorununuzun uzun süre çalışan bir CPU sürüş sorgusu olmadığı durumlarda başvuru olarak buraya eklenmiştir. Bekleme süresi uzun olan sorgularla ilgili sorunları gidermek için bunu kullanabilirsiniz.
Performans sorunlarını bekleyen bir sorguyu iyileştirmek için, beklemenin ne kadar sürdüğünü ve performans sorununun nerede olduğunu (bekleme türü) belirleyin. Bekleme türü onaylandıktan sonra bekleme süresini azaltın veya beklemeyi tamamen ortadan kaldırın.
Yaklaşık bekleme süresini hesaplamak için, sorgunun geçen zamanından CPU süresini (çalışan saati) çıkarın. Genellikle CPU süresi gerçek yürütme süresidir ve sorgunun ömrünün kalan bölümü bekler.
Yaklaşık bekleme süresini hesaplama örnekleri:
Geçen Süre (ms) | CPU Süresi (ms) | Bekleme süresi (ms) |
---|---|---|
3200 | 3000 | 200 |
7080 | 1000 | 6080 |
Performans sorununu belirleme veya bekleme
Geçmiş uzun süre bekleyen sorguları (örneğin, >geçen sürenin %20'sini bekleme süresi) tanımlamak için aşağıdaki sorguyu çalıştırın. Bu sorgu, SQL Server başlangıcından bu yana önbelleğe alınmış sorgu planları için performans istatistiklerini kullanır.
SELECT t.text, qs.total_elapsed_time / qs.execution_count AS avg_elapsed_time, qs.total_worker_time / qs.execution_count AS avg_cpu_time, (qs.total_elapsed_time - qs.total_worker_time) / qs.execution_count AS avg_wait_time, qs.total_logical_reads / qs.execution_count AS avg_logical_reads, qs.total_logical_writes / qs.execution_count AS avg_writes, qs.total_elapsed_time AS cumulative_elapsed_time FROM sys.dm_exec_query_stats qs CROSS apply sys.Dm_exec_sql_text (sql_handle) t WHERE (qs.total_elapsed_time - qs.total_worker_time) / qs.total_elapsed_time > 0.2 ORDER BY qs.total_elapsed_time / qs.execution_count DESC
Şu anda 500 ms'den uzun bekleme süreleriyle yürütülen sorguları belirlemek için aşağıdaki sorguyu çalıştırın:
SELECT r.session_id, r.wait_type, r.wait_time AS wait_time_ms FROM sys.dm_exec_requests r JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id WHERE wait_time > 500 AND is_user_process = 1
Sorgu planı toplayabilirseniz SSMS'deki yürütme planı özelliklerindenWaitStats'ı denetleyin:
- Sorguyu Fiili Yürütme Planını Ekle açık olarak çalıştırın.
- Yürütme planı sekmesinde en soldaki işleci sağ tıklatın
- Özellikler'i ve ardından WaitStats özelliğini seçin.
- WaitTimeMs ve WaitType değerlerini denetleyin.
PSSDiag/SQLdiag veya SQL LogScout LightPerf/GeneralPerf senaryolarını biliyorsanız, performans istatistiklerini toplamak ve SQL Server örneğinizde bekleyen sorguları belirlemek için bunlardan birini kullanmayı göz önünde bulundurun. Toplanan veri dosyalarını içeri aktarabilir ve SQL Nexus ile performans verilerini analiz edebilirsiniz.
Beklemeleri ortadan kaldırmaya veya azaltmaya yardımcı olacak başvurular
Her bekleme türünün nedenleri ve çözümleri farklılık gösterir. Tüm bekleme türlerini çözümlemek için tek bir genel yöntem yoktur. Sık karşılaşılan bekleme türü sorunlarını gidermeye ve çözmeye yönelik makaleler şunlardır:
- Engelleme sorunlarını anlama ve çözme (LCK_M_*)
- Azure SQL Veritabanı engelleme sorunlarını anlama ve çözme
- G/Ç sorunlarının (PAGEIOLATCH_*, WRITELOG, IO_COMPLETION, BACKUPIO) neden olduğu yavaş SQL Server performansı sorunlarını giderme
- SQL Server'da son sayfa ekleme PAGELATCH_EX çekişme sorununu çözme
- Bellek açıklamaları ve çözümleri verir (RESOURCE_SEMAPHORE)
- ASYNC_NETWORK_IO bekleme türünden kaynaklanan yavaş sorgularda sorun giderme
- AlwaysOn Kullanılabilirlik Grupları ile Yüksek HADR_SYNC_COMMIT bekleme türü sorunlarını giderme
- Nasıl Çalışır: CMEMTHREAD ve Hata Ayıklama
- Paralellik beklemelerini eyleme dönüştürülebilir hale getirme (CXPACKET ve CXCONSUMER)
- THREADPOOL bekleme
Birçok Bekleme türünün açıklamaları ve bunların ne gösterdiği için Bekleme Türleri'ndeki tabloya bakın.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin