SQL Server 2014'ü güçlü bir sunucuda çalıştıran 1 TB'lık büyük bir veritabanımız var. Her şey birkaç yıl boyunca iyi çalıştı. Yaklaşık 2 hafta önce, aşağıdakileri içeren tam bir bakım yaptık: Tüm yazılım güncellemelerini yükleyin; tüm dizinleri ve kompakt DB dosyalarını yeniden oluşturun. Ancak, gerçek aşama aynı olduğunda DB'nin CPU kullanımının% 100'ün üzerinde% 150'ye çıkmasını beklemiyorduk.
Birçok sorun giderme işleminden sonra, bunu çok basit bir sorguya daralttık, ancak bir çözüm bulamadık. Sorgu son derece basittir:
select top 1 EventID from EventLog with (nolock) order by EventID
Her zaman yaklaşık 1,5 saniye sürer! Ancak, "desc" ile benzer bir sorgu her zaman yaklaşık 0 ms sürer:
select top 1 EventID from EventLog with (nolock) order by EventID desc
PTable'ın yaklaşık 500 milyon satırı vardır; bigint veri türüne sahip EventID
birincil kümelenmiş dizin sütunu (sıralı ASC
) (Kimlik sütunu). Üstteki tabloya veri ekleyen birden çok iş parçacığı vardır (daha büyük EventID'ler) ve alttan veri silinen 1 iş parçacığı vardır (daha küçük EventID'ler).
SMS'lerde, iki sorgunun her zaman aynı yürütme planını kullandığını doğruladık:
Kümelenmiş dizin taraması;
Tahmini ve gerçek satır numaralarının her ikisi de 1'dir;
Tahmini ve gerçek yürütme sayısı 1'dir;
Tahmini G / Ç maliyeti 8500 (Yüksek gibi görünüyor)
Art arda çalıştırılırsa, Sorgu maliyeti her ikisi için de aynı% 50'dir.
Dizin istatistiklerini güncelledim with fullscan
, sorun devam etti; Dizini yeniden oluşturdum ve sorun yarım gün boyunca gitmiş gibi görünüyordu, ama geri döndü.
IO istatistiklerini aşağıdakilerle açtım:
set statistics io on
ardından iki sorguyu art arda çalıştırdı ve aşağıdaki bilgileri buldu:
(İlk sorgu için yavaş olan)
'PTable' tablosu. Tarama sayısı 1, mantıksal okuma 407670, fiziksel okuma 0, okuma öncesinde 0 okuma, lob mantıksal okuma 0, lob fiziksel okuma 0, lob okuma öncesinde 0 okuma.
(İkinci sorgu için hızlı olan)
'PTable' tablosu. Tarama sayısı 1, mantıksal okumalar 4, fiziksel okumalar 0, okuma öncesinde okumalar 0, lob mantıksal okumalar 0, lob fiziksel okumalar 0, lob okuma öncesinde okumalar 0.
Mantıksal okumalardaki büyük farklılığa dikkat edin. Endeks her iki durumda da kullanılır.
Endeks parçalanması biraz açıklayabilir, ancak etkinin çok küçük olduğuna inanıyorum; ve sorun daha önce hiç olmadı. Başka bir kanıt ben gibi bir sorgu çalıştırmak ise:
select * from EventLog with (nolock) where EventID=xxxx
Xxxx'i tablodaki en küçük EventID'lere ayarlasam bile, sorgu her zaman hızlıdır.
Kontrol ettik ve kilitleme / engelleme sorunu yok.
Not: Yukarıdaki sorunu basitleştirmeye çalıştım. "PTable" aslında "EventLog" dur; PID
olduğunu EventID
.
NOLOCK
İpucu olmadan aynı sonuç testini alıyorum .
Birisi yardım edebilir mi?
XML'de daha ayrıntılı sorgu yürütme planları aşağıdaki gibidir:
https://www.brentozar.com/pastetheplan/?id=SJ3eiVnob
https://www.brentozar.com/pastetheplan/?id=r1rOjVhoZ
Tablo ifadesi oluşturmanın önemli olduğunu düşünmüyorum. Bu eski bir veritabanı ve bakım kadar uzun süre mükemmel çalışıyor. Kendimizi birçok araştırma yaptık ve sorumun verdiği bilgiye daralttık.
Tablo normalde EventID
sütunun birincil anahtar olan bir tür identity
sütun olduğu şekilde oluşturulmuştur bigint
. Şu anda, sanırım sorun dizin parçalanmasıyla ilgili. Endeksin yeniden oluşturulmasından hemen sonra, sorun yarım gün boyunca ortadan kalkmış gibi görünüyordu; ama neden bu kadar çabuk geri döndü ...?