Bu, aşırı yüklenmiş bir sunucunun belirtisi mi?


12

Bir uygulamada yavaşlamaları teşhis etmeye çalışıyorum. Bunun için SQL Server genişletilmiş olayları günlüğe kaydettim .

  • Bu soru için belirli bir saklı yordam bakıyorum.
  • Ancak, bir elmadan elmaya araştırma olarak eşit olarak kullanılabilecek bir düzine saklı yordam seti vardır.
  • ve saklı yordamlardan birini el ile çalıştırdığımda, her zaman hızlı çalışır
  • ve bir kullanıcı tekrar denerse: hızlı çalışır.

Saklı yordamın yürütme süreleri çok değişkendir. Bu saklı yordamın birçok yürütme <1s içinde döner:

resim açıklamasını buraya girin

Ve bu "hızlı" kova için, 1 saniyeden çok daha az. Aslında 90 ms civarında:

resim açıklamasını buraya girin

Ancak 2s, 3s, 4s saniye beklemek zorunda olan uzun bir kullanıcı kuyruğu var. Bazıları 12s, 13s, 14s beklemek zorunda. Sonra 22'ler, 23'ler, 24'ler beklemek zorunda olan gerçekten fakir ruhlar var.

Ve 30 saniye sonra, istemci uygulaması pes eder, sorguyu iptal eder ve kullanıcı 30 saniye beklemek zorunda kaldı .

Nedeni bulmak için korelasyon

Bu yüzden ilişkilendirmeye çalıştım:

  • süre vs mantıksal okumalar
  • fiziksel okumalara karşı süre
  • süre vs işlemci süresi

Ve hiçbiri herhangi bir korelasyon vermiyor gibi görünmüyor; hiçbiri neden gibi görünmüyor

  • süre mantıksal okumalara göre : ister biraz ister mantıksal okuma olsun, süre hala çılgınca dalgalanıyor :

    resim açıklamasını buraya girin

  • süresi ve fiziksel okumalar : sorgu önbellekten sunulmamış olsa ve çok fazla fiziksel okumaya ihtiyaç duyulsa bile, süreyi etkilemez:

    resim açıklamasını buraya girin

  • süresi vs cpu süresi : Sorgunun 0s CPU zamanı mı yoksa 2.5s CPU zamanı mı aldığı, süreler aynı değişkenliğe sahiptir:

    resim açıklamasını buraya girin

Bonus : Süre v Fiziksel Okumalar ve Süre v CPU saatinin çok benzer göründüğünü fark ettim . CPU zamanını fiziksel okumalarla ilişkilendirmeye çalışırsam bu kanıtlanmıştır:

resim açıklamasını buraya girin

G / Ç'den çok fazla CPU kullanımı olduğu ortaya çıkıyor. Kim biliyordu!

Peki , yürütme süresindeki farklılıkları açıklayabilecek sorguyu yürütme eylemi hakkında hiçbir şey yoksa, bunun CPU veya sabit sürücü ile ilgisi olmadığı anlamına mı geliyor?

CPU veya sabit sürücü darboğazdaysa; darboğaz olmaz mıydı?

Darboğazın CPU olduğunu varsayarsak; CPU'nun bu sunucu için yetersiz olduğundan:

  • daha fazla CPU zamanı kullanan yürütmeler daha uzun sürmez mi?
  • aşırı CPU kullanarak başkaları ile tamamlamak zorunda beri?

Sabit sürücüler için de benzer şekilde. Sabit sürücünün bir darboğaz olduğunu varsayarsak; sabit sürücülerin bu sunucu için yeterli rasgele geçişe sahip olmadığı:

  • daha fazla fiziksel okuma kullanan yürütmeler daha uzun sürmez mi?
  • aşırı yüklenmiş sabit sürücü G / Ç kullanarak başkaları ile tamamlamak zorunda çünkü?

Saklı yordamın kendisi herhangi bir yazma işlemi gerçekleştirmez veya gerektirmez.

  • Genellikle 0 satır (% 90) döndürür.
  • Bazen 1 satır (% 7) döndürür.
  • Nadiren 2 satır (% 1.4) döndürür.
  • Ve en kötü durumlarda 2'den fazla satır döndürdü (bir kez 12 satır döndürüyor)

Yani çılgınca bir veri hacmi döndürüyor gibi değil.

Sunucu CPU Kullanımı

Sunucunun İşlemci Kullanımı yaklaşık% 1.8, ara sıra% 18'e varan bir artışla ortalama CPU yükü bir sorun gibi görünmüyor:

resim açıklamasını buraya girin

Yani sunucu CPU aşırı yüklü görünmüyor.

Ama sunucu olan sanal ...

Evrenin dışında bir şey mi var?

Hayal edebileceğim tek şey, sunucunun evreninin dışında var olan bir şey.

  • mantıklı değilse
  • ve fiziksel okumalar değil
  • ve cpu kullanımı değil
  • ve CPU yükü değil

Ve saklı yordamın parametreleri gibi değil (çünkü aynı sorguyu elle yayınlamak ve 27 saniye sürmez - ~ 0 saniye sürer).

Başka bir şey, aynı derlenmiş saklı yordamı çalıştırmak için bazen 0 saniye yerine 30 saniye süren sunucuyu açıklayabilir.

  • kontrol noktaları?

Sanal bir sunucudur

  • Ev sahibi aşırı yüklendi mi?
  • Aynı ana bilgisayardaki başka bir VM?

Sunucunun genişletilmiş olaylarını gözden geçirme; bir sorgu aniden 20 saniye sürdüğünde özellikle başka bir şey olmaz. İyi çalışır, sonra iyi çalışmaya karar verir:

  • 2 saniye
  • 1 saniye
  • 30 saniye
  • 3 saniye
  • 2 saniye

Ve bulabileceğim, özellikle yorucu bir şey yok. Her 2 saatlik işlem günlüğü yedeklemesi sırasında değil.

Başka ne olabilir ki ?

"Sunucu" dışında söyleyebileceğim bir şey var mı ?

Düzenleme : Günün saatine göre ilişkilendir

Süreleri her şeyle ilişkilendirdiğimi fark ettim:

  • mantıksal okumalar
  • fiziksel okumalar
  • CPU kullanımı

Ama ilişkilendirmediğim tek şey günün zamanı idi . Belki her-2 saatlik işlem günlük yedekleme olan bir sorun.

Ya da belki yavaşlamalar do kontrol noktalarında sırasında atıyormuş meydana?

Hayır:

resim açıklamasını buraya girin

Intel Xeon Gold Dört Çekirdekli 6142.

Düzenle - Kişiler sorgu yürütme planını varsayıyor

İnsanlar sorgu yürütme planlarının "hızlı" ve "yavaş" arasında farklı olması gerektiğini varsaymaktadır. Onlar değil.

Ve bunu incelemeden hemen görebiliriz.

Uzun soru süresinin "kötü" bir yürütme planı nedeniyle olmadığını biliyoruz:

  • daha mantıklı okumalar alan
  • daha fazla birleşim ve anahtar aramalardan daha fazla CPU tüketen

Çünkü okumalardaki bir artış veya CPU'daki artış, sorgu süresinin artmasının bir nedeni olsaydı, bunu daha önce görmüş olabilirdik. Hiçbir korelasyon yoktur.

Ancak, süreyi CPU-okuma alanı ürün metriğiyle ilişkilendirmeye çalışalım:

resim açıklamasını buraya girin

Daha az bir korelasyon olur - bu bir paradokstur.


Düzenleme : Çok sayıda değer içeren Excel dağılım grafiklerinde bir hatayı gidermek için dağılım diyagramları güncelleştirildi.

Sonraki adımlar

Bir sonraki adımım, 5 saniye sonra birisinin engellenen sorgular için etkinlik oluşturması için sunucuya sahip olmak olacak :

EXEC sp_configure 'blocked process threshold', '5';
RECONFIGURE

Sorguların 4 saniye boyunca engellenip engellenmediğini açıklamaz . Ama belki bir sorguyu 5 saniye boyunca engelleyen her şey de 4 saniye boyunca bazılarını engeller.

Yavaş Planlar

Yürütülen iki saklı yordamın yavaş planı:

  • `EXECUTE FindFrob @CustomerID = 7383, @StartDate = '20190725 04: 00: 00.000', @EndDate = '20190726 04: 00: 00.000'
  • `EXECUTE FindFrob @CustomerID = 7383, @StartDate = '20190725 04: 00: 00.000', @EndDate = '20190726 04: 00: 00.000'

Aynı parametrelerle aynı saklı yordam, arka arkaya çalışır:

| Duration (us) | CPU time (us) | Logical reads | Physical reads | 
|---------------|---------------|---------------|----------------|
|    13,984,446 |        47,000 |         5,110 |            771 |
|     4,603,566 |        47,000 |         5,126 |            740 |

Çağrı 1:

|--Nested Loops(Left Semi Join, OUTER REFERENCES:([Contoso2].[dbo].[Frobs].[FrobGUID]) OPTIMIZED)
    |--Nested Loops(Inner Join, OUTER REFERENCES:([Contoso2].[dbo].[FrobTransactions].[OnFrobGUID]))
    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([Contoso2].[dbo].[FrobTransactions].[RowNumber]) OPTIMIZED)
    |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([tpi].[TransactionGUID]) OPTIMIZED)
    |    |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([tpi].[TransactionGUID]) OPTIMIZED)
    |    |    |    |    |--Index Seek(OBJECT:([Contoso2].[dbo].[TransactionPatronInfo].[IX_TransactionPatronInfo_CustomerID_TransactionGUID] AS [tpi]), SEEK:([tpi].[CustomerID]=[@CustomerID]) ORDERED FORWARD)
    |    |    |    |    |--Index Seek(OBJECT:([Contoso2].[dbo].[Transactions].[IX_Transactions_TransactionGUIDTransactionDate]), SEEK:([Contoso2].[dbo].[Transactions].[TransactionGUID]=[Contoso2].[dbo
    |    |    |    |--Index Seek(OBJECT:([Contoso2].[dbo].[FrobTransactions].[IX_FrobTransactions2_MoneyAppearsOncePerTransaction]), SEEK:([Contoso2].[dbo].[FrobTransactions].[TransactionGUID]=[Contos
    |    |    |--Clustered Index Seek(OBJECT:([Contoso2].[dbo].[FrobTransactions].[IX_FrobTransactions_RowNumber]), SEEK:([Contoso2].[dbo].[FrobTransactions].[RowNumber]=[Contoso2].[dbo].[Fin
    |    |--Clustered Index Seek(OBJECT:([Contoso2].[dbo].[Frobs].[PK_Frobs_FrobGUID]), SEEK:([Contoso2].[dbo].[Frobs].[FrobGUID]=[Contoso2].[dbo].[FrobTransactions].[OnFrobGUID]),  WHERE:([Contos
    |--Filter(WHERE:([Expr1009]>(1)))
     |--Compute Scalar(DEFINE:([Expr1009]=CONVERT_IMPLICIT(int,[Expr1012],0)))
          |--Stream Aggregate(DEFINE:([Expr1012]=Count(*)))
           |--Index Seek(OBJECT:([Contoso2].[dbo].[FrobTransactions].[IX_FrobTransactins_OnFrobGUID]), SEEK:([Contoso2].[dbo].[FrobTransactions].[OnFrobGUID]=[Contoso2].[dbo].[Frobs].[LC

Çağrı 2

|--Nested Loops(Left Semi Join, OUTER REFERENCES:([Contoso2].[dbo].[Frobs].[FrobGUID]) OPTIMIZED)
    |--Nested Loops(Inner Join, OUTER REFERENCES:([Contoso2].[dbo].[FrobTransactions].[OnFrobGUID]))
    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([Contoso2].[dbo].[FrobTransactions].[RowNumber]) OPTIMIZED)
    |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([tpi].[TransactionGUID]) OPTIMIZED)
    |    |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([tpi].[TransactionGUID]) OPTIMIZED)
    |    |    |    |    |--Index Seek(OBJECT:([Contoso2].[dbo].[TransactionPatronInfo].[IX_TransactionPatronInfo_CustomerID_TransactionGUID] AS [tpi]), SEEK:([tpi].[CustomerID]=[@CustomerID]) ORDERED FORWARD)
    |    |    |    |    |--Index Seek(OBJECT:([Contoso2].[dbo].[Transactions].[IX_Transactions_TransactionGUIDTransactionDate]), SEEK:([Contoso2].[dbo].[Transactions].[TransactionGUID]=[Contoso2].[dbo
    |    |    |    |--Index Seek(OBJECT:([Contoso2].[dbo].[FrobTransactions].[IX_FrobTransactions2_MoneyAppearsOncePerTransaction]), SEEK:([Contoso2].[dbo].[FrobTransactions].[TransactionGUID]=[Contos
    |    |    |--Clustered Index Seek(OBJECT:([Contoso2].[dbo].[FrobTransactions].[IX_FrobTransactions_RowNumber]), SEEK:([Contoso2].[dbo].[FrobTransactions].[RowNumber]=[Contoso2].[dbo].[Fin
    |    |--Clustered Index Seek(OBJECT:([Contoso2].[dbo].[Frobs].[PK_Frobs_FrobGUID]), SEEK:([Contoso2].[dbo].[Frobs].[FrobGUID]=[Contoso2].[dbo].[FrobTransactions].[OnFrobGUID]),  WHERE:([Contos
    |--Filter(WHERE:([Expr1009]>(1)))
     |--Compute Scalar(DEFINE:([Expr1009]=CONVERT_IMPLICIT(int,[Expr1012],0)))
          |--Stream Aggregate(DEFINE:([Expr1012]=Count(*)))
           |--Index Seek(OBJECT:([Contoso2].[dbo].[FrobTransactions].[IX_FrobTransactins_OnFrobGUID]), SEEK:([Contoso2].[dbo].[FrobTransactions].[OnFrobGUID]=[Contoso2].[dbo].[Frobs].[LC

Planların aynı olması mantıklıdır; aynı parametrelerle aynı saklı yordamı yürütüyor.


2
Sorgu planlarını gönderebilir misiniz - good run vs bad run?
Kin Shah

4
Buradan ilk tahminim engellenecek ...
Tibor Karaszi

3
Bunu kim reddetti? Sorgu planlarından yoksun olmasına rağmen çok ayrıntılı, ayrıntılı bir şekilde araştırılmış bir soru! Benden +1!
Vérace

4
Sorgu planlarının "özdeş" olduğu sonucuna nasıl vardınız? Sadece aynı şekle sahip olduklarını mı söylüyorsun? Biz de bir yere gönderin ki biz de karşılaştıralım. Sadece bize aynı olduklarını söylemek aynı oldukları anlamına gelmez.
Aaron Bertrand

3
PasteThePlan kullanarak acutal yürütme planlarını eklemek, sorgunun ne beklediğiyle ilgili bize bir fikir verebilir.
Randi Vertongen

Yanıtlar:


2

Wait_stats'a bir göz atın ve SQL sunucunuzda en büyük darboğazların ne olduğunu gösterecektir.

Son zamanlarda harici bir uygulamanın zaman zaman yavaş olduğu bir sorunla karşılaştım. Sunucunun kendisinde saklı yordamları çalıştırmak her zaman hızlıydı.

Performans izleme, SQL Önbellekleri veya sunucudaki RAM kullanımı ve IO ile hiç endişe duymayacak bir şey göstermedi.

Soruşturmayı daraltmaya yardımcı olan, SQL tarafından toplanan bekleme istatistiklerini sorgulamaktı. sys.dm_os_wait_stats

SQLSkills web sitesindeki mükemmel komut dosyası, en çok yaşadıklarınızı gösterecektir. Ardından, nedenleri belirlemek için aramanızı daraltabilirsiniz.

Ne bekler büyük sorunlar olduğunu öğrendikten sonra bu komut dosyası hangi oturum / veritabanı beklemek yaşıyor daraltmak yardımcı olacaktır:

SELECT OSW.session_id,
       OSW.wait_duration_ms,
       OSW.wait_type,
       DB_NAME(EXR.database_id) AS DatabaseName
FROM sys.dm_os_waiting_tasks OSW
INNER JOIN sys.dm_exec_sessions EXS ON OSW.session_id = EXS.session_id
INNER JOIN sys.dm_exec_requests EXR ON EXR.session_id = OSW.session_id
OPTION(Recompile);

Yukarıdaki sorgu ve diğer ayrıntılar MSSQLTips web sitesinden .

sp_BlitzFirstBrent Ozar adlı dan komut web de yavaşlamalar neden neler olduğunu gösterecektir.

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.