Değil emin bir hata, eğer kendi başına ama kesinlikle ilginç bir olay bu. Çevrimiçi bölüm yeniden yapılandırmaları, SQL Server 2014'te yenidir, bu nedenle bununla ilgili bazı iç bağlantılar olabilir.
İşte size en iyi açıklamam. Artan istatistikler kesinlikle tüm bölümlerin aynı oranda örneklenmesini gerektirir, böylece motor istatistik sayfalarını birleştirdiğinde örneklenen dağılımın karşılaştırılabilir olduğundan emin olabilir. REBUILD
mutlaka% 100 numune hızında veri örnekleri. Bölüm 9'daki% 100 örnekleme oranının her zaman bölümlerin geri kalanının kesin örnekleme oranı olacağının garantisi yoktur. Bu nedenle, motor örnekleri birleştiremez gibi görünüyor ve boş bir istatistik blobuna ulaşıyorsunuz. Ancak, istatistik nesnesi hala orada:
select
check_time = sysdatetime(),
schema_name = sh.name,
table_name = t.name,
stat_name = s.name,
index_name = i.name,
stats_column = index_col(quotename(sh.name)+'.'+quotename(t.name),s.stats_id,1),
s.stats_id,
s.has_filter,
s.is_incremental,
s.auto_created,
sp.last_updated,
sp.rows,
sp.rows_sampled,
sp.unfiltered_rows,
modification_counter
from sys.stats s
join sys.tables t
on s.object_id = t.object_id
join sys.schemas sh
on t.schema_id = sh.schema_id
left join sys.indexes i
on s.object_id = i.object_id
and s.name = i.name
outer apply sys.dm_db_stats_properties(s.object_id, s.stats_id) sp
where t.name = 'TransactionHistory' and sh.name = 'dbo'
Blob'u istediğiniz sayıda yolla doldurabilirsiniz:
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE;
veya
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE ON PARTITIONS (9);
veya bu nesneyi kullanarak bir sorgu planının ilk derlemesinde AutoStats'ın güncellenmesini bekleyebilirsiniz:
-- look at my creative query
select *
from dbo.TransactionHistory
where TransactionDate = '20140101';
Bunların hepsini söyledikten sonra, Erin Stellato'nun bu aydınlatıcı yazısı , artımlı istatistiklerin önemli bir eksikliği olarak algılanan şeyin altını çiziyor . Bölüm düzeyindeki veriler, sorgulayıcı oluşturmada optimize edici tarafından kullanılmaz, bu da artan istatistiklerin varsayılan faydasını azaltır. Öyleyse, artımlı istatistiklerin mevcut faydası nedir? Temel faydalarının, büyük tabloları geleneksel istatistiklere göre daha tutarlı bir şekilde örnekleme kabiliyetine sahip olduğunu söyleyebilirim.
Örneğinizi kullanarak işte işler böyle görünüyor:
set statistics time on;
update statistics dbo.TransactionHistory(IDX_ProductId)
with fullscan;
--SQL Server Execution Times:
-- CPU time = 94 ms, elapsed time = 131 ms.
update statistics dbo.TransactionHistory(IDX_ProductId)
with resample on partitions(2);
--SQL Server Execution Times:
-- CPU time = 0 ms, elapsed time = 5 ms.
drop index IDX_ProductId On dbo.TransactionHistory;
CREATE NONCLUSTERED INDEX IDX_ProductId ON dbo.TransactionHistory (ProductId)
WITH (DATA_COMPRESSION = ROW)
ON [PRIMARY]
update statistics dbo.TransactionHistory(IDX_ProductId)
with fullscan;
--SQL Server Execution Times:
-- CPU time = 76 ms, elapsed time = 66 ms.
Artımlı istatistiklerle ilgili tam kapsamlı bir istatistik güncellemesi 131 msn. Bölünmemiş hizalanmış istatistiklerle ilgili tam kapsamlı bir istatistik güncellemesi 66 msn. Tek tek istatistik sayfalarını ana histograma birleştirmek için yapılan genel gider nedeniyle hizalı olmayan istatistik daha yavaştır. Bununla birlikte, bölüm hizalanmış istatistik nesnesini kullanarak, bir bölümü güncelleyebilir ve onu 5 ms'de ana histogram bloğuna geri birleştirebiliriz. Bu noktada, bu noktada artımlı istatistiklere sahip yönetici bir kararla karşı karşıya kalmaktadır. Genel istatistik bakım sürelerini yalnızca bölümleri güncelleyerek geleneksel olarak güncellemeleri gerekebilecek şekilde azaltabilirler veya daha yüksek örnekleme hızları ile deney yapabilirler, böylece önceki bakım zamanlarıyla aynı zaman diliminde örneklenen potansiyel olarak daha fazla satır alabilirler. Eski bakım penceresinde yeterli boşluk sağlar ikincisi kudreti sorguları daha doğru istatistiklere dayalı iyi planlar elde bir yere çok büyük bir masanın üzerine itme istatistikleri. Bu bir garanti değildir ve kilometreniz değişebilir.
Okuyucu 66 ms'nin bu tablodaki acı istatistiklerin güncelleme süresi olmadığını görebilir, bu yüzden stackexchange veri setinde bir test kurmayı denedim. İndirdiğim son dökümü içinde 6.418.608 gönderi var (StackOverflow gönderileri ve 2012'deki tüm gönderiler - benim açımdan veri hatası hariç).
Verileri bölümlere [CreationDate]
ayırdım çünkü ... demo.
İşte bazı oldukça standart senaryolar için bazı zamanlamalar: (% 100 - dizin yeniden oluşturma, varsayılan - istatistikler otomatik güncelleme veya UPDATE STATISTICS
belirli bir örnekleme hızı olmadan:
- Fullscan ile Artımlı Olmayan İstatistikler Yaratın: CPU süresi = 23500 ms, geçen süre = 22521 ms.
- Fullscan ile Artımlı İstatistik Oluşturma: CPU süresi = 20406 ms, geçen süre = 15413 ms.
- Artımlı Olmayan İstatistiği Varsayılan Örnek Hızı ile Güncelleyin: CPU süresi = 406 ms, geçen süre = 408 ms.
- Varsayılan Örnek Hızı ile Artımlı İstatistik Güncelleme: CPU süresi = 453 ms, geçen süre = 507 ms.
Diyelim ki bu varsayılan senaryolardan daha sofistike olduk ve% 10'luk bir örnekleme oranının, bakım süresini makul bir zaman diliminde tutarken bize gereken planlara ulaşması gereken minimum oran olduğuna karar verdik.
- Artımlı Olmayan İstatistiği, yüzde 10 örnekle güncelleyin: CPU süresi = 2344 ms, geçen süre = 2441 ms.
- Güncelleme Artımlı İstatistiği yüzde 10 örnekle: CPU süresi = 2344 ms, geçen süre = 2388 ms.
Şimdiye kadar artan bir istatistiklere sahip olmanın net bir faydası yok. Bununla birlikte, belgelendirilmemiş sys.dm_db_stats_properties_internal()
DMV'den (aşağıda) yararlanırsak, hangi bölümleri güncellemek isteyebileceğiniz konusunda bir fikir edinebilirsiniz. Diyelim ki bölüm 3'teki verilerde değişiklikler yaptık ve istatistiklerin gelen sorgular için taze olmasını istiyoruz. İşte seçeneklerimiz:
- Varsayılan Olarak Artımlı Olmayan Güncelle (ayrıca Otomatik İstatistik Güncelleştirmesi'nin varsayılan davranışı): 408 ms.
- Artımlı Olmayan% 10'da güncelleme: 2441 ms.
- Artımlı İstatistikleri Güncelle, Bölüm 3 Yeniden Örnekle (% 10 - tanımlanmış örnekleme oranımız): CPU süresi = 63 ms, geçen süre = 63 ms.
İşte karar vermemiz gereken yer. 63 ms kazanıyor muyuz? bölüm tabanlı istatistik güncellemeleri mi, yoksa örnekleme oranını daha da yükseltiyor muyuz? Diyelim ki, örneklemenin ilk vuruşunu% 50 oranında artan bir istatistikle almaya hazırız:
- Artımlı İstatistikleri% 50'de güncelle: geçen süre = 16840 ms.
- Artımlı İstatistikleri Güncelle, Örnek 3 ile Bölüm 3 (% 50 - yeni güncelleme zamanımız): geçen zaman = 295 ms.
Verilerimiz hakkında daha iyi tahminler yapmak için optimize ediciyi ayarlayarak çok daha fazla veri örnekleyebiliyoruz (henüz bölüm düzeyinde istatistikler kullanmasa da) ve bunu şimdi daha hızlı yapabiliyoruz. artımlı istatistikler.
Anlamak için son bir eğlenceli şey. Senkron istatistik güncellemeleri ne durumda? Autostatlar devreye girdiğinde bile% 50 numune oranı korunuyor mu?
3. bölümdeki verileri sildim ve CreationDate üzerinde bir sorgu çalıştırdım ve kontrol ettikten sonra oranları aynı sorgu ile kontrol ettim. % 50 numune oranı korunmuştur.
Bu yüzden, uzun lafın kısası: Artımlı İstatistikler, doğru miktarda düşünce ve ilk kurulum çalışması için yararlı bir araç olabilir. Ancak, çözmeye çalıştığınız sorunu bilmelisiniz ve ardından uygun şekilde çözmelisiniz. Kötü önem düzeyi tahminleri alıyorsanız, size olabilecek stratejik örnekleme oranı ve bazı yatırım müdahale ile daha iyi planlar elde edebilmek. Ancak, kullanılan histogram, bölüm düzeyinde bir bilgi değil, birleştirilmiş, birleştirilmiş istatistikler sayfası olduğundan, bu avantajın yalnızca küçük bir kısmını alıyorsunuz. Bakım pencerenizde ağrı hissediyorsanız, belki artımlı istatistikler size yardımcı olabilir, ancak muhtemelen yüksek dokunuşlu bir bakım müdahale süreci ayarlamanızı gerektirecektir. Ne olursa olsun,:
- Temel tabloya göre bölümlere ayrılmayan indekslerle oluşturulan istatistikler.
- AlwaysOn okunabilir ikincil veritabanlarında oluşturulan istatistikler.
- Salt okunur veritabanlarında oluşturulan istatistikler.
- Filtrelenmiş dizinlerde oluşturulan istatistikler.
- İstatistikler görünümlerde oluşturuldu.
- İç tablolarda oluşturulan istatistikler.
- Uzamsal dizinler veya XML dizinleri ile oluşturulan istatistikler.
Bu yardımcı olur umarım
select
sysdatetime(),
schema_name = sh.name,
table_name = t.name,
stat_name = s.name,
index_name = i.name,
leading_column = index_col(quotename(sh.name)+'.'+quotename(t.name),s.stats_id,1),
s.stats_id,
parition_number = isnull(sp.partition_number,1),
s.has_filter,
s.is_incremental,
s.auto_created,
sp.last_updated,
sp.rows,
sp.rows_sampled,
sp.unfiltered_rows,
modification_counter = coalesce(sp.modification_counter, n1.modification_counter)
from sys.stats s
join sys.tables t
on s.object_id = t.object_id
join sys.schemas sh
on t.schema_id = sh.schema_id
left join sys.indexes i
on s.object_id = i.object_id
and s.name = i.name
cross apply sys.dm_db_stats_properties_internal(s.object_id, s.stats_id) sp
outer apply sys.dm_db_stats_properties_internal(s.object_id, s.stats_id) n1
where n1.node_id = 1
and (
(is_incremental = 0)
or
(is_incremental = 1 and sp.partition_number is not null)
)
and t.name = 'Posts'
and s.name like 'st_posts%'
order by s.stats_id,isnull(sp.partition_number,1)