Query Store aramasını hiç bitirme


10

Benim soru / sorun benzeyen o baştan söylerim bu öncekine ama emin nedeni ya da başlangıç bilgileri aynı ise olduğumdan beri, biraz daha ayrıntı ile sorumu göndermek için karar verdi.

Eldeki sayı:

  • garip bir saatte (iş gününün sonuna yakın) bir üretim örneği düzensiz davranmaya başlar:
    • Örneğin yüksek CPU (~% 30'luk bir taban çizgisinden yaklaşık iki katına çıktı ve hala büyüyordu)
    • artan işlem / saniye (uygulama yükünde herhangi bir değişiklik görülmese de)
    • artan boş oturum sayısı
    • bu davranışı hiç göstermeyen oturumlar arasında garip engelleme olayları (taahhüt edilmeyen oturumları okumak bile engellemeye neden oluyordu)
    • aralık için en fazla bekler, kilitler 2. sırada, sayfa dışı mandal vardı

İlk soruşturma:

  • sp_whoIsActive kullanarak, izleme aracımız tarafından yürütülen bir sorgunun son derece yavaş çalışmaya ve daha önce gerçekleşmeyen çok fazla CPU yakalamaya karar verdiğini gördük;
  • izolasyon seviyesi taahhüt edilmeden okundu;
  • tuhaf sayılar gördüğümüz plana baktık: StatementEstRows = "3.86846e + 010", yaklaşık 150 TB tahmini veri döndürülüyor
  • izleme aracının bir sorgu izleme özelliğinin neden olduğundan şüphelendik, bu nedenle özelliği devre dışı bıraktık (herhangi bir sorunun farkında olup olmadığını kontrol etmek için sağlayıcımızla bir bilet açtık)
  • bu ilk olaydan, birkaç kez daha oldu, oturumu her öldürdüğümüzde, her şey normale döner;
  • Sorgunun MS tarafından BOL'de Sorgu Deposu izleme için kullanılan sorgulardan birine çok benzer olduğunu fark ediyoruz - Performansta son zamanlarda gerileyen sorgular (zaman içinde farklı noktaları karşılaştırarak)
  • aynı sorguyu manuel olarak çalıştırıyoruz ve aynı davranışı görüyoruz (CPU sürekli artıyor, mandal beklemelerini artırıyor, beklenmedik kilitler vb.)

Suçlu sorgu:

Select qt.query_sql_text, 
    q.query_id, 
    qt.query_text_id, 
    rs1.runtime_stats_id AS runtime_stats_id_1,
    interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time), 
    p1.plan_id AS plan_1, 
    rs1.avg_duration AS avg_duration_1, 
    rs2.avg_duration AS avg_duration_2,
    p2.plan_id AS plan_2, 
    interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time), 
    rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt 
Inner Join sys.query_store_query AS q 
    ON qt.query_text_id = q.query_text_id 
Inner Join sys.query_store_plan AS p1 
    ON q.query_id = p1.query_id 
Inner Join sys.query_store_runtime_stats AS rs1 
    ON p1.plan_id = rs1.plan_id 
Inner Join sys.query_store_runtime_stats_interval AS rsi1 
    ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id 
 Inner Join sys.query_store_plan AS p2 
    ON q.query_id = p2.query_id 
Inner Join sys.query_store_runtime_stats AS rs2 
    ON p2.plan_id = rs2.plan_id 
Inner Join sys.query_store_runtime_stats_interval AS rsi2 
    ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
Where rsi1.start_time > DATEADD(hour, -48, GETUTCDATE()) 
    AND rsi2.start_time > rsi1.start_time 
    AND p1.plan_id <> p2.plan_id
    AND rs2.avg_duration > rs1.avg_duration * 2
Order By q.query_id, rsi1.start_time, rsi2.start_time

Ayarlar ve bilgiler:

  • Windows Server 2012R2 kümesinde SQL Server 2016 SP1 CU4 Enterprise
  • Sorgu Deposu etkin ve varsayılan olarak yapılandırıldı (ayar değiştirilmedi)
  • SQL 2005 örneğinden içe aktarılan veritabanı (ve yine de uyumluluk düzeyi 100'de)

Deneysel gözlem:

  • Son derece tuhaf istatistikler nedeniyle, kötü tahmini planda kullanılan tüm * plan_persist ** nesnelerini aldık (henüz gerçek bir plan yok, sorgunun hiç bitmesine neden olmadık) ve kontrol edilen istatistikler, planda kullanılan bazı dizinlerde herhangi bir istatistik yoktu (DBCC SHOWSTATISTICS hiçbir şey döndürmedi, sys.stats arasından seçim yapın, bazı dizinler için NULL stats_date () işlevi gösterdi

Hızlı ve kirli çözüm:

  • Sorgu Deposu ile ilgili sistem nesneleri üzerinde el ile eksik istatistikler oluşturun veya
  • sorguyu yeni CE'yi (traceflag) kullanarak çalışmaya zorlayın - bu da gerekli istatistikleri oluşturur / günceller veya
  • veritabanının uyumluluk düzeyini 130 olarak değiştirin (varsayılan olarak yeni CE'yi kullanır)

Yani, asıl sorum şu olurdu:

Sorgu Deposu'ndaki bir sorgu neden tüm örnekte performans sorunlarına neden olur? Query Store ile hata bölgesinde miyiz?

Not: Bazı dosyaları (baskı ekranları, ES istatistikleri ve planları) kısa bir süre içinde yükleyeceğim.

Dropbox'a dosyalar eklendi .

Plan 1 - Üretimde ilk tuhaf tahmini plan

Plan 2 - Bir test ortamında gerçek plan, eski CE, (aynı davranış, aynı tuhaf istatistikler)

Plan 3 - Bir test ortamında yeni plan, yeni CE


1
Sorgu deposunu devre dışı bıraktık, kök nedenin ne olduğundan emin olduk (kesin olarak 1'den fazla sorunumuz vardı). Sonunda, CPU sorgu deposundan istatistikleri görüntülemek için tıkladığımız her şeyi hızlandıracaktı.
A_V

Yanıtlar:


6

Cevabımda söylediğim gibi, ampirik test sys.plan_persisted * sistem nesnelerinde, üzerinde hiçbir istatistik oluşturulmamış (hiçbiri) indeksler olduğunu gösterdi. Bunun nedeni, veritabanının bir SQL 2005 örneğinden taşınması ve uyumluluk düzeyi 100'de bir süre tutulması nedeniyle yeni CE'nin kullanılmadığından şüpheleniyorum.

Satır sayım kontrolü:

Select count(1) from NoNameDB.sys.plan_persist_runtime_stats with (nolock) --60362   
Select count(1) from NoNameDB.sys.plan_persist_plan with (nolock) --1853    
Select count(1) from NoNameDB.sys.plan_persist_runtime_stats_interval with (nolock) --671    
Select count(1) from NoNameDB.sys.plan_persist_query with (nolock) --1091    
Select count(1) from NoNameDB.sys.plan_persist_query_text with (nolock) --911

Bu, ilk tahminlerin yanlış olduğunu gösterdi. Bir DAC bağlantısı ile yapılır, aksi takdirde tablolar sorgulanamaz.

İstatistik kontrolü:

DBCC SHOW_STATISTICS ('sys.plan_persist_runtime_stats_interval', plan_persist_runtime_stats_interval_cidx);    
DBCC SHOW_STATISTICS ('sys.plan_persist_runtime_stats', plan_persist_runtime_stats_idx1);    
DBCC SHOW_STATISTICS ('sys.plan_persist_runtime_stats', plan_persist_runtime_stats_cidx);    
DBCC SHOW_STATISTICS ('sys.plan_persist_plan', plan_persist_plan_cidx);    
DBCC SHOW_STATISTICS ('sys.plan_persist_plan', plan_persist_plan_idx1);    
DBCC SHOW_STATISTICS ('sys.plan_persist_query', plan_persist_query_cidx)    
DBCC SHOW_STATISTICS ('sys.plan_persist_query_text', plan_persist_query_text_cidx);

Bu, bazı endekslerin boş istatistiklere sahip olduğunu (eksik, hiçbiri, sıfır) gösterdi.

İlk düzeltme:

UPDATE STATISTICS sys.plan_persist_runtime_stats WITH fullscan;
UPDATE STATISTICS sys.plan_persist_plan WITH fullscan;
UPDATE STATISTICS sys.plan_persist_runtime_stats_interval WITH fullscan;
UPDATE STATISTICS sys.plan_persist_query WITH fullscan;
UPDATE STATISTICS sys.plan_persist_query_text WITH fullscan;

Bu tür istatistikleri düzeltti ve sorguyu 10-12 saniye içinde bitirdi.

İkinci düzeltme :

(yalnızca test ortamında doğrulandı) ve sorgu için en iyi istatistikleri gösterdiğinden, büyük olasılıkla uygun olanı, veritabanının uyumluluk düzeyini 130 olarak değiştirmekti. Sonuç, sorgunun yaklaşık 10-12 saniye içinde sona ermesi oldu. normal sayı istatistikleri (10 bin satır).

Ara düzeltme :

DBCC TRACEON (2312) -- new CE

Sistem gizli tablolarındaki istatistiklerle ilgili bazı yardımlar .


3

SSMS'de gerçek planı açar ve CPU kullanımına bakarsanız (veya XML'i incelerseniz) görülebilen temel sorun, bir TVF düğümü 32'dir. Yavaş Sorgu Deposu sorgularındaki suçlu, bellek içi TVF'lere tekrar erişimdir .

TVF maliyeti

Bu TVF'lerden kaç satır döndürüldüğünün önemi yoktur, yalnızca bunlara kaç kez erişildiği. Düzeltme, planlarınızı birden çok kez okumaktan uzak tutmak için yapabileceğiniz her şey olacaktır.

Sınırlı hata ayıklama (hem beceri hem de harcanan zaman) temelinde, hipotezim, Query Store verilerinin belirli bellek içi bileşeni için atanan belleğin tamamının her TVF yürütmesiyle taranmasıdır. sp_query_store_flush_dbVeya ile bu bellek ayırmayı etkileyemedim DBCC FREESYSTEMCACHE.

Şimdiye kadar başarılı geçici çözümler arasında plan kılavuzları, ipucu ( OPTION(HASH JOIN, LOOP JOIN)şu ana kadar benim için yeterince iyi çalıştı) ve Sorgu Deposu sorgularını bir AG'nin salt okunur düğümünde çalıştırma yer alıyor.

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.