Analizler#1191
Demo modu

Analiz #1191

Bitti

Hedef: sorgu 0x72D0DB6D73F273CF · DB-10 · dönem 2026-10-03 → 2026-10-09

Çalıştırma

Model
gemma4:12b (gemma4)Kurum içi
Prompt şablonu
#16
Token (giriş / çıkış)
12.077 / 1.267
Süre
101,1 sn
Onarım
0
Kural bulgusu
2
Getirim (bağlama giren)
KB 2 · profil 5 · vaka 0

Özet

güven: Orta

Sorgu, sys.sysrowsets üzerindeki bir Index Spool (F1) nedeniyle performans kaybı yaşamaktadır. Bu durum, sorgu sırasında geçici bir indeks oluşturulması gerektirdiğini ve yüksek CPU kullanımı (F2) nedeniyle gecikmeye yol açtığını göstermektedir.

Kök nedenler

  • sys.sysrowsets üzerindeki Index Spool (Eager Index Spool) kullanımı, sorgu sırasında geçici bir indeks oluşturulmasına neden olmaktadır. F1
  • Sorgu, yüksek CPU maliyetine sahip bir çalışma profilinde (99% CPU) çalışmaktadır. F2

Bulgular

2 bulgu
IdCiddiyetKuralBaşlıkKanıt
F1yüksek INDEX_SPOOLGeçici index (Eager Index Spool) — SQL Server iç nesnesi, sorgu yeniden yazılmalıOptimizer sys.sysrowsets için sorgu sırasında geçici index kuruyor (her çalıştırmada yeniden; maliyet payı %50,4): NodeId 37: anahtar [idmajor, idminor], 16 kez aranıyor, 40.658 satır okunup kuruluyor. Kaynak SQL Server iç nesnesi (sistem görünümü/fonksiyonu): kalıcı index kurulamaz; spool'u doğuran join/IN yapısı yeniden yazılmalı.
F2düşük RUNTIME_PROFILESüre bileşimi: CPU, bekleme ve kuyrukort. süre 7792,5 ms, ort. CPU 7716,4 ms (%99 CPU, 7 çalışma) — süre çoğunlukla CPU: okunan/işlenen satır azaltılmalı (erişim yolu), bekleme ikincil; en uzun tek çalışma 15.669,0 ms; QDS bekleme kategorileri (dönem toplamı): Memory 2.656 ms, CPU 1.523 ms, Buffer IO 31 ms; memory grant beklemesi: sorgu bellek izni için kuyruğa giriyor (plan isteği 544 KB); eşzamanlı grant baskısı ve max server memory incelenmeli, grant gerektirmeyen plan (seek + stream aggregate / sıralı erişim) bu kuyruğu da kaldırır

Plan özeti

Plan özeti
Plan tipi: tahmini; statement sayısı 1; toplam maliyet 3,516; tahmini satır 16,1
CE sürümü: 170; DOP: ?; paralel değil: MaxDOPSetToOne
Memory grant (KB): istenen 544 (tahmini plan; verilen/kullanılan yalnız actual planda)
Operatörler (maliyet sırasıyla):

Benzer vakalar

LLM bağlamına girdi; örnektir, kanıt değildir

Bağlama benzer vaka girmedi.

Analizi güçlendirecek ek bilgiler

isteğe bağlı; verilirse yeniden analiz edin
  • Plan tahmini (estimated): actual plan verilirse gerçek satır ve çalışma sayılarıyla tahmin hataları doğrulanır; kurallar şu an optimizer tahminlerine dayanıyor.
  • Sorgu parametreli ve değerleri bilinmiyor: yavaş çalışmanın parametre değerleri (ya da değerleri içeren actual plan) kardinalite tahmin hatasını ve parametre hassasiyetini açıklar.

Öneriler

İngilizce çeviri onay bekliyor

Korpusa ve LLM bağlamına bu analizin İngilizce çevirisi girer; onaylanmadan vaka korpusa girmez.

Bu analiz korpusta değil: onaylanmış ya da uygulanmış öneri yok

Korpusa yalnız onaylanmış ya da uygulanıp sahada izi görülen çözüm girer; aynı sorgunun yalnız en son onaylanan analizi korpusta kalır.

Korpusa girerse yaklaşık 40 sorgunun benzer vaka listesine girebilir.

T-SQL refactor — model önerisi

uyarılı karar bekliyor
OrijinalÖneri
SELECT 1, N'DB-10', i.object_id, i.index_id, CAST('20261009' AS datetime), ISNULL(u.user_seeks, 0), ISNULL(u.user_scans, 0), ISNULL(u.user_lookups, 0), ISNULL(u.user_updates, 0), SELECT 1, N'DB-10', i.object_id, i.index_id, CAST('20261009' AS datetime), ISNULL(u.user_seeks, 0), ISNULL(u.user_scans, 0), ISNULL(u.user_lookups, 0), ISNULL(u.user_updates, 0),
CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_seek) ELSE CONVERT(datetime, u.last_user_seek AT TIME ZONE @tz AT TIME ZONE N'UTC') END, CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_scan) ELSE CONVERT(datetime, u.last_user_scan AT TIME ZONE @tz AT TIME ZONE N'UTC') END, CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_lookup) ELSE CONVERT(datetime, u.last_user_lookup AT TIME ZONE @tz AT TIME ZONE N'UTC') END, CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_update) ELSE CONVERT(datetime, u.last_user_update AT TIME ZONE @tz AT TIME ZONE N'UTC') END, CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_seek) ELSE CONVERT(datetime, u.last_user_seek AT TIME ZONE @tz AT TIME ZONE N'UTC') END,
CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_scan) ELSE CONVERT(datetime, u.last_user_scan AT TIME ZONE @tz AT TIME ZONE N'UTC') END,
CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_lookup) ELSE CONVERT(datetime, u.last_user_lookup AT TIME ZONE @tz AT TIME ZONE N'UTC') END,
CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_update) ELSE CONVERT(datetime, u.last_user_update AT TIME ZONE @tz AT TIME ZONE N'UTC') END,
(SELECT CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, sqlserver_start_time) ELSE CONVERT(datetime, sqlserver_start_time AT TIME ZONE @tz AT TIME ZONE N'UTC') END FROM sys.dm_os_sys_info), (SELECT CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, sqlserver_start_time) ELSE CONVERT(datetime, sqlserver_start_time AT TIME ZONE @tz AT TIME ZONE N'UTC') END FROM sys.dm_os_sys_info),
sz.RowCnt, sz.SizeMB, op.Ins, op.Upd, op.Del, op.Alloc, op.LockMs, op.LatchMs, op.IoMs sz.RowCnt, sz.SizeMB, op.Ins, op.Upd, op.Del, op.Alloc, op.LockMs, op.LatchMs, op.IoMs
FROM sys.indexes AS i JOIN sys.objects AS o ON o.object_id = i.object_id FROM sys.indexes AS i
INNER JOIN sys.objects AS o ON o.object_id = i.object_id
LEFT JOIN sys.dm_db_index_usage_stats AS u ON u.database_id = DB_ID() AND u.object_id = i.object_id AND u.index_id = i.index_id LEFT JOIN sys.dm_db_index_usage_stats AS u ON u.database_id = DB_ID() AND u.object_id = i.object_id AND u.index_id = i.index_id
OUTER APPLY (SELECT SUM(ps.row_count) AS RowCnt, CAST(SUM(ps.used_page_count) * 8 / 1024.0 AS decimal(18,2)) AS SizeMB OUTER APPLY (SELECT SUM(ps.row_count) AS RowCnt, CAST(SUM(ps.used_page_count) * 8 / 1024.0 AS decimal(18,2)) AS SizeMB
FROM sys.dm_db_partition_stats AS ps WHERE ps.object_id = i.object_id AND ps.index_id = i.index_id) AS sz FROM sys.dm_db_partition_stats AS ps WHERE ps.object_id = i.object_id AND ps.index_id = i.index_id) AS sz
OUTER APPLY (SELECT SUM(x.leaf_insert_count) AS Ins, SUM(x.leaf_update_count) AS Upd, SUM(x.leaf_delete_count) AS Del, OUTER APPLY (SELECT SUM(x.leaf_insert_count) AS Ins, SUM(x.leaf_update_count) AS Upd, SUM(x.leaf_delete_count) AS Del,
SUM(x.leaf_allocation_count) AS Alloc, SUM(x.row_lock_wait_in_ms) AS LockMs, SUM(x.page_latch_wait_in_ms) AS LatchMs, SUM(x.leaf_allocation_count) AS Alloc, SUM(x.row_lock_wait_in_ms) AS LockMs, SUM(x.page_latch_wait_in_ms) AS LatchMs,
SUM(x.page_io_latch_wait_in_ms) AS IoMs SUM(x.page_io_latch_wait_in_ms) AS IoMs
FROM sys.dm_db_index_operational_stats(DB_ID(), i.object_id, i.index_id, NULL) AS x) AS op FROM sys.dm_db_index_operational_stats(DB_ID(), i.object_id, i.index_id, NULL) AS x) AS op
WHERE o.is_ms_shipped = 0 AND o.type IN ('U','V') AND i.is_hypothetical = 0 WHERE o.is_ms_shipped = 0 AND o.type IN ('U','V') AND i.is_hypothetical = 0
Script
SELECT 1, N'DB-10', i.object_id, i.index_id, CAST('20261009' AS datetime), ISNULL(u.user_seeks, 0), ISNULL(u.user_scans, 0), ISNULL(u.user_lookups, 0), ISNULL(u.user_updates, 0), 
       CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_seek) ELSE CONVERT(datetime, u.last_user_seek AT TIME ZONE @tz AT TIME ZONE N'UTC') END, 
       CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_scan) ELSE CONVERT(datetime, u.last_user_scan AT TIME ZONE @tz AT TIME ZONE N'UTC') END, 
       CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_lookup) ELSE CONVERT(datetime, u.last_user_lookup AT TIME ZONE @tz AT TIME ZONE N'UTC') END, 
       CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, u.last_user_update) ELSE CONVERT(datetime, u.last_user_update AT TIME ZONE @tz AT TIME ZONE N'UTC') END, 
       (SELECT CASE WHEN @tz IS NULL THEN DATEADD(minute, @off, sqlserver_start_time) ELSE CONVERT(datetime, sqlserver_start_time AT TIME ZONE @tz AT TIME ZONE N'UTC') END FROM sys.dm_os_sys_info), 
       sz.RowCnt, sz.SizeMB, op.Ins, op.Upd, op.Del, op.Alloc, op.LockMs, op.LatchMs, op.IoMs
       FROM sys.indexes AS i 
       INNER JOIN sys.objects AS o ON o.object_id = i.object_id
       LEFT JOIN sys.dm_db_index_usage_stats AS u ON u.database_id = DB_ID() AND u.object_id = i.object_id AND u.index_id = i.index_id
       OUTER APPLY (SELECT SUM(ps.row_count) AS RowCnt, CAST(SUM(ps.used_page_count) * 8 / 1024.0 AS decimal(18,2)) AS SizeMB
                    FROM sys.dm_db_partition_stats AS ps WHERE ps.object_id = i.object_id AND ps.index_id = i.index_id) AS sz
       OUTER APPLY (SELECT SUM(x.leaf_insert_count) AS Ins, SUM(x.leaf_update_count) AS Upd, SUM(x.leaf_delete_count) AS Del, 
                           SUM(x.leaf_allocation_count) AS Alloc, SUM(x.row_lock_wait_in_ms) AS LockMs, SUM(x.page_latch_wait_in_ms) AS LatchMs, 
                           SUM(x.page_io_latch_wait_in_ms) AS IoMs
                    FROM sys.dm_db_index_operational_stats(DB_ID(), i.object_id, i.index_id, NULL) AS x) AS op
       WHERE o.is_ms_shipped = 0 AND o.type IN ('U','V') AND i.is_hypothetical = 0

planForcing: Sorgu için tespit edilen en iyi planın (plan 857) SP_QUERY_STORE_FORCE_PLAN ile zorlanması, kısa vadeli bir çözüm olarak değerlendirilebilir.

uyarılı karar bekliyor
Script
EXEC sp_query_store_force_plan @query_id = 3747, @plan_id = 857

Asistana sor

yalnız bu analizin kanıtıyla

Bu analiz hakkında soru sorun: cevap yalnız bulgulara (F), önerilere (R), sorgu, plan ve metadata'ya dayanır; kanıt gösteremeyen cevap gösterilmez.