DEFINITIONS

Definitions More Info.
Definition ID571
TitleSQL
CategoryNOTES
DefinitionStatistics konusu ve guncellemeleri
Definition Description/* STATISTICS İstatistikler, Query Optimizier tarafından sorgu planı oluşturulurken daha performanslı bir plan oluşturmak için kullanılan, tablodaki verinin dağılımını gösteren istatistik bütünüdür.
İstatistikler sayesinde, sorgu planı (Query Plan) oluşturulurken sorgudaki where bloğunda kullanılan kolon için dönecek tahmini kayıt sayısı bulunur. Bulunan bu değer index’e erişim şeklini belirler.
Temel amaç, datayı en hızlı ve en az maliyetli şekilde kullanıcının karşısına getirmektir.
Oluşturabileceğimiz istatistik seçenekleri:
-- Index'lenmemiş sütunlar,
-- Composite index içindeki ilk sütun dışında kalan sütunlar,
-- Koşul verilmiş Computed sütunlar
-- Image,text ve ntext veri tiplerine sahip olmaan sütunlar. */
Create statistics istatistik_ismi ON (tablo_adı veya view_adı)(sütunadı)

/* AŞAĞIDAKİ DURUMLARDA İSTATİSTİKLERİN GÜNCELLENMESİ GEREKEBİLİR
-- Tablo içinde herhangi bir kayıt girmeden önce, index oluşturulacaksa,
-- Tablo Truncated ise -- Çok az aynı tür veri içeren birçok kayıt, tabloya ekleniyorsa */
UPDATE STATISTICS tablo_adı veya view_adı index_adı veya istatistik_adı
/* STATISTICS GÖRÜNTÜLENMESİ Bir index veya bir sütun hakkındaki istatistik bilgileri:
DBCC SHOW_STATISTICS ifadesi ile görüntüleyebiliriz.
Alıcanak Bilgilerin Bazıları Sütun adı Açıklama Updated İstatistiklerin en son güncellenme tarihi Rows Tablo içindeki satırların sayısı Rows sampled İstatisk bilgiler için,
örnek satır sayısı Steps Dağıltılmış adım sayısı Density ilk index sütunun yoğunluğu Average key length İlk index sütunun ortalam uzunluğu All density Index sütunlarının yoğunluğu (Kullanım sıklığı)
Average lenght Index sütunlarının uzunluğu */
-- örneğin
create nonclustered index IX_City on Person.Address (City)
go DBCC SHOW_STATISTICS('Person.Address',IX_City)
/* Çıkan sonucun değerlendirmesi:
Sorgu sonucunda 3 farklı kayıt seti gelmektedir.
-- İlk kayıt setinde istatistik hakkında isim, son güncellenme tarihi, tablo kayıt sayısı, örneklenen kayıt sayısı gibi bilgiler bulunmaktadır.
-- İkinci kayıt setinde ise kolon ya da kolon gruplarının yoğunluk (density) bilgileri bulunmaktadır.
Buradaki hesaplama şu şekildedir. Örneğin City kolonu için tabloda toplam 575 farklı City bulunmakta, dolayısıyla City kolonu için DENSİTY DEĞERİ 1/575 = 0,0017 olarak hesaplanmaktadır.
-- Üçüncü ve son kayıt setinde bizi en çok ilgilendiren kısım yani City kolonundaki değerlerin histogramı bir başka deyişle dağılımı bulunmaktadır. Histogram bölümü maksimum 200 satırdan oluşabilir.
O yüzden dikkatinizi çekerse bu kayıt setinde bütün City’ler bulunmamaktadır. Şimdi “Bootrop”(şehri için) satırı için histogram değerlerini detaylı inceleyelim. */
-- Range_Rows : “Bootrop” ile histogramdaki bir önceki değer olan “Bonn” arasında bulunan KAYIT SAYISINI verir.
select * from Person.Address where City>'Bonn' and City<'Bottrop'
-- Range Row aslında bu sorgu demektir Bu sorgu sonucu 28 dir
-- EQ_Rows : City kolonu “Bottrop” olan kayıt sayısını verir. 57 toplam kayıt
select * from Person.Address where City='Bottrop'
-- sonucu 57 toplam kayıt var
-- Distinct_Range_Rows : “Bootrop” ile “Bonn” arasındaki tekil City sayısını verir.
select City from Person.Address where City>'Bonn' and City<'Bottrop' group by City
/* -- Avg_Range_Rows : “Bonn” ile “Bootrap” arasındaki şehirlerin her birine düşen ortalama kayıt sayısını verir.
Diyelim ki bu 2 şehir arasında 5 farklı şehir ve toplam 50 kayıt var. Bu durumda tahmini olarak her bir şehre 10 kayıt düşecektir. Bu kolonun formülü: */
Avg_Range_Rows= Range_Rows /Distinct_Range_Rows
--şeklinde gösterilebilir. örneğin:
set statistics profile on
select * from Person.Address where City='Bottrop' /*
Görüldüğü gibi IX_City istatistiği kesin veya tahmini olarak tabloda her City için kaç satır olduğunu göstermektedir.
Bu şekilde City kolonu üzerinden çekilen bir sorguda Query Plan hazırlanma aşamasında toplamda kaç kayıt döneceği tahmin edilir ve bu değere göre index’e erişim şekli yani index seek mi yoksa scan mi yapılacağı belirlenir.
Plan’ın detayını incelediğimizde istatistiğe göre bu sorgu sonucunda 57 kayıt döneceğini görüyoruz.
Gerçekten de select sorgusu bize 57 kayıt döndürüyor. Bu aşamada istatistik şu şekilde çalışıyor;
sorgulanmak istenen kayıt yani “Bootrop”. İstatistiğin histogramında aranır.
Histogram dağılımında bu kayıt direk belirtilmiş dolayısıyla kaç kayıt döneceği bilgisi için direk olarak EQ_Rows kolonunu kullanabiliriz ki bu kolonda 57 yazmakta.
Dolayısıyla istatistik vasıtasıyla daha sorgu çalışmadan bu sorgu için 57 kayıt döneceğini bilebiliyoruz. */
Şimdi histogramda direk geçmeyen bir kayıt için sorgulama yapalım. Örneğin “Bonn” ile “Bootrop” arasında bulunan “Bothell” için arama yapalım
set statistics profile on
select * from Person.Address where City='Bothell'
/* “Bothell” histogramda “Bonn” ile “Bootrop” arasına denk gelmekte. Dolayısıyla bizi ilgilendiren kolon Range_Rows ve Distinct_Range_Rows kolonları. Range_Rows alanında 28 yazmakta.
Yani Bothell’in denk geldiği “Bonn” ile “Bootrop” arasında 28 kayıt bulunmakta. Distinct_Range_Rows alanında ise 3 yazmakta.
Yani “Bonn” ile “Bootrop” arasında 3 farklı şehir bulunmakta.
Dolayısıyla 28/3’ten her bir şehre denk gelen kayıt sayısı 9,33. Avg_Range_Rows alanından da bu rakamı direk olarak öğrenmemiz mümkün.
28 kaydı direk 3’e bölerek her bir şehir için 9 kayıt vardır diye tahmin ettik. Belki de bu 28 kaydın tamamı tek bir şehre ait. Bunu bilemiyoruz.
Yani historgram da direk geçmeyen kayıtlar için tam sonuç bilmemiz mümkün değil. Gerçekten de sorgu sonucuna baktığımızda “Boothell” için 9 kayıt değil 26 kayıt döndüğünü görüyoruz.
Dolayısıyla histogramda direk kırılım olarak geçmeyen kayıtlarda tahmini bir değer söyleyebilmekteyiz ki bunun da çoğu zaman gerçek değere tutmayacağını belirtebiliriz. */

/* İSTATİSTİKLERİN GÜNCEL OLMASININ ÖNEMİ Bir önceki bölümde de belirttiğim gibi sorgu planı oluşturulma aşamasında istatistikler kullanılarak kaç kayıt geleceği tahmin edilir ve bu yapılan tahmin üzerinden bir maliyet hesabı yapılır ,
kayıt sayısı nispeten az ise genellikle index seek yapılmasına, fazla ise index’e scan yaparak erişilmesine karar verilir.
Örneğin bir tablodaki toplam sayfaların yarısına index seek metodu ile erişmek index’in tüm sayfalarına index scan metodu ile erişmekten çok daha yüksek maliyete sahip olacaktır.
Bu yüzden böyle bir durumda index’e erişim metodu index seek yerine index scan olarak belirlenir.
Dolayısıyla bu tahminleri düzgün bir şekilde yapabilmek için istatistiklerin güncel olması çok önemlidir.
Veri değiştirme dili (DML : insert, update, delete) komutlarının çalışması sonucu tabloda değişiklik yapıldığında istatistiğin histogramında da değişiklik olur.
Eğer bu durumda istatistik güncel olmaz ise hala eski dağılımı göstereceğinden dolayı yanlış kayıt sayısı tahmini ortaya çıkacaktır.
Bu durum index’e erişim metodunun gerçek verilere dayanmadan belirlenmesine neden olacağından bazı performans sorunlarına yol açabilir.
Şimdi aşağıdaki örnekle beraber bu durumu derinlemesine inceleyelim.
Bu örneğimde City bilgisi “Seattle” olan kayıtları sorgulayacağım. İlk olarak bu sorgu sonucunda kaç kayıt gelmesinin tahmin edildiğini ve kaç kayıt geldiğini görelim.
*/
set statistics profile on
select * from Person.Address where City='Seattle'
sonuç: 141 kayıt DBCC SHOW_STATISTICS('Person.Address',IX_City)
/*
seattle ait plandaki tahmini sayı da 141 İstatistik 141 kayıt geleceğini tahmin ediyor ve sorgu sonucunda da 141 kayıt geldiğini görüyoruz.
Bu örnekte gelmesi tahmin edilen kayıt sayısı nispeten fazla olduğu için Query Optimizier index erişim metodu olarak NonClustered index seek yerine Clustered index scan yapmayı daha uygun buluyor.
Execution Plan’da index scan yapıldığını görebiliriz. */

/*Şimdi 141 olan kayıt sayısını 21’e indirelim. Bunun için City bilgisi “Seattle” olan kayıtların ilk 120 tanesini “Istanbul” olarak güncelliyorum.
update top (120) Person.Address Set City='Istanbul' where City='Seattle'
-- şimdi seattle sorgunu tekrar çekelim ve execution plana tekrar bakalım */
select * from Person.Address where City='Seattle'

/*--sonuç 23 tane seattle ait kayıt var */
DBCC SHOW_STATISTICS('Personel.Address',IX_City)
/* Buradaki seattle ait plan bilgisi halen 141 güncel değil */
/*Gördüğünüz gibi gerçekleşen kayıt sayısı 21 iken istatistik hala kayıt sayısını 141 olarak tahmin etmekte.
Çünkü istatistik hala güncel değil. Peki bu durumun bize zararı ne?
İstatistik güncel olmadığı için Query Optimizier 141 kayıt döneceğini tahmin ederek Clustered Index Scan metodunun NonClustered Index Seek metodundan daha performanslı bir hareket olduğunu düşünüyor.
Oysaki gerçekte 21 kayıt döndüğü için NONCLUSTERED INDEX SEEK METODU daha performanslı olacaktır.
Gerçekte seçilmesi gereken index erişim metodu Index Seek olmalıdır.
Şimdi istatistiği güncelleyelim ve sorgunun planına tekrar bakalım. */
set statistics profile on
Update statistics Person.Address (IX_City)
select * from Person.Address where City='Seattle'
set statistics profile off
DBCC SHOW_STATISTICS('Person.Address',IX_City)
/* Gördüğünüz gibi istatistiği güncelledikten sonra artık 21 kayıt getirileceği tahmin ediliyor Daha önce Clustered Index Scan metodu tercih edilirken istatistik güncellendikten sonra NonClustered Index Seek metodu tercih edilmeye başlanmış durumda. */
/* İSTATİSTİĞİN GÜNCELLENMESİ İstatistiklerin güncel olmasının performans açısından ne kadar önemli olduğuna bir önceki bölümde değinmiştik. Bu bölümde istatistiklerin en son ne zaman güncellendiğine nasıl bakacağımıza ve istatistikleri nasıl güncelleyebileceğimize bakıyor olacağız.
İstatistiğin en son ne zaman güncellendiğini aşağıdaki objeler vasıtasıyla bulabiliriz.
• sp_autostats
• DBCC SHOW_STATISTICS
• STATS_DATE */
Örneğin IX_City istatistiğinin en son ne zaman güncellendiğine sp_autostats sistem SP’si ile bakalım
exec sp_autostats @tblname='Person.Address', @indname='IX_City'
/* İstatistikleri güncellemek için UPDATE STATISTICS komutunu kullanabiliriz.
Örneğin Person.Address.IX_City istatistiğini aşağıdaki komut vasıtasıyla güncelleyebiliriz. */
UPDATE STATISTICS Person.Address IX_City
/* CREATE STATISTICS’te olduğu gibi UPDATE STATISTICS’te de FULL SCAN anahtarını kullanarak örneklem olarak tablodaki kayıtların tamamının seçilmesini sağlayabiliriz. */
UPDATE STATISTICS Person.Address IX_City WITH FULLSCAN
/*UPDATE STATISTICS komutu ile istatistikler tek tek güncelleyebileceği gibi veritabanında bulunan tüm istatistikler sp_updatestats komutu ile güncellenmesi sağlanabilir.
-- Örneğin AdventureWorks veritabanında bulunan tüm istatistikleri güncellemek için aşağıdaki kodu kullanabiliriz.*/
USE AdventureWorks2012;
GO EXEC sp_updatestats
/* Bu komut vasıtasıyla sadece güncellenmesine ihtiyaç olunan istatistikler güncellenecektir.
Bu ihtiyaç, daha sonra detaylarını göreceğimiz sysindexes.rowmodctr kolonuna bakılarak karar verilmektedir
İSTATİSTİKLERİN OTOMATİK OLUŞTURULMA VE GÜNCELLENME PARAMETRELERİ create database statsdeneme
Daha önce de belirttiğim gibi istatistikler CREATE STATISTICS komutu ile manuel olarak oluşturabilir.
Bu yöntemlerin dışında istatistik oluşturulma ve güncellenme işi otomatik olarak ta yapılabilir.
Bunun için veritabanı özelliklerinde değişiklik yapılması gerekmektedir.
Bu parametreler aşağıdaki gibidir.
• Auto_Create_Statistics
• Auto_Update_Statistics
• Auto_Update_Statistics_Aysnc Auto_Create_Statistics
Bu özellik aktif hale getirildiğinde, sorgu yapıldığı zaman where bloğunda bulunan kolonlar için SQL Server Query Optimizier otomatik olarak istatistik oluşturur.
OFF durumunda iken ise istatistikler otomatik olarak oluşturulmaz.
Daha öncede belirttiğim gibi istatistikler sorgu planı oluşturulma kısmında çok önemli bir görev üstlenmektedir.
Sorguların daha performanslı olması için istatistiklerin önemi büyük olduğundan dolayı Auto_Create_Statistics veritabanı özelliğinin “best practice” değeri AKTİF olmasıdır.
Bir index oluşturulduğunda Auto_Create_Statistics veritabanı özelliği AKTİF olsa da PASİF olsa da istatistik oluşturulur.
Eğer index birden fazla kolondan oluşan bir bütünleşik (composit) index ise sadece ilk kolon için istatistik oluşturulur.
Index için her hâlükârda otomatik olarak istatistik oluşmasına rağmen,
sadece index’in ilk kolonu için istatistik oluşturulduğundan dolayı Auto_Create_Statistics veritabanı özelliğinin AKTİF yapılması önerilir.
Çünkü bu sayede where bloğunda bulunan diğer kolonlar için de istatistik otomatik olarak oluşturulacak ve bu şekilde birden fazla kolonun birleşmesinden dönecek satır sayısı daha iyi bir şekilde tahmin edilerek daha iyi bir sorgu plan oluşturulacaktır.
SQL Server 2005 ile beraber veritabanında bulunan istatistikler sys.stats tablosuna sorgu çekilerek bakılabilir.
2005’ten önceki sürümlerde istatistiklerin meta verilerine sysindexes sistem tablosundan bakılmaktaydı. Hala daha bazı işlemler için sysindexes sistem tablosundaki bilgiler kullanılmaktadır.
İlerleyen bölümlerde bunun detayını görüyor olacağız.
Auto_Create_Statistics veritabanı özelliğinin AKTİF olması durumunda Query Optimizier tarafından otomatik olarak oluşturulan index’ler _WA_ ön ekiyle başlar.
Index’in oluşturulmasıyla oluşan istatistikler ise Index’in adını alır.
Auto_Create_Statistics bir veritabanı özelliğidir ve aşağıdaki şekilde AKTİF hale getirilir. */
alter database StatsDeneme
set Auto_Create_Statistics ON
/*Şimdi Auto_Create_Statistics veritabanı özelliğinin AKTİF veya PASİF durumunda iken istatistik oluşumlarına göz atalım.
İlk olarak parametreyi OFF olarak set edip istatistiğin otomatik olarak oluşup oluşmadığını gözlemleyeceğiz.
Bir çalışma DB'si açılır */
Use StatsDeneme
GO
/*Auto_Create_Statistics parametresi off yapılır */
alter database StatsDeneme set
Auto_Create_Statistics OFF
GO
/*Bir çalışma tablosu create edilir */
create table StatsDeneme (col1 int, col2 varchar(10), col3 varchar(10))
GO
/*Tabloya veri basılır */
insert StatsDeneme Values (1,'a','b')
GO
/*Select sorgusu çekilir*/
select * from StatsDeneme where col1=1 and col2='a'
/*Tablo üzerinde bulunan istatistikler sorgulanır*/
select * from sys.stats where object_id=object_id('StatsDeneme')
GO
*/tablo drop edilir. */
drop table StatsDeneme
GO
/*Özellik PASİF olduğu için otomatik olarak istatistik oluşturulmadı.
Şimdi aynı işlemi Auto_Create_Statistics veritabanı özelliğini AKTİF yaparak tekrar deneyelim.
Bir çalışma DB'si açılır*/
Use StatsDeneme
GO
/*Auto_Create_Statistics parametresi off yapılır*/
alter database StatsDeneme
set Auto_Create_Statistics ON
GO
/*Bir çalışma tablosu create edilir*/
create table StatsDeneme (col1 int, col2 varchar(10), col3 varchar(10)) GO
/*Tabloya veri basılır */
insert StatsDeneme Values (1,'a','b') GO
/*Select sorgusu çekilir */
select * from StatsDeneme where col1=1 and col2='a'
/*Tablo üzerinde bulunan istatistikler sorgulanır */
select * from sys.stats where object_id=object_id('StatsDeneme')
GO
/*tablo drop edilir. */
drop table StatsDeneme
GO
/* Gördüğünüz gibi where bloğunda 2 kolon olduğu için 2 kolon içinde birer istatistik otomatik olarak oluşturuldu.
AUTO_UPDATE_STATİSTİCS İstatistiğin temsil ettiği kolonun verisi insert ya da update işlemleri sonucunda değiştiğinde, artık istatistiğin dağılımı veriyi tam olarak temsil edememeye başlar.
Daha önce Person.Address örneğinde üzerinde durduğum gibi, istatistiğin dağılımından çıkarılan estimated row count yani tahmin edilen kayıt sayısı bilgisi,
veri güncellenmesine rağmen istatistik güncellenmediği için doğru sonuç vermeyecektir.
Bu durumda istatistiğe bakılarak veriye erişim için index scan metodu kullanılmasına karar verilmesine rağmen belki de index seek metodu ile erişim çok daha anlamlı olacaktır.
Bu yüzden istatistiklerin olması kadar güncel olması da en iyi Query Plan’ın oluşturulması yani performans açısından oldukça önem taşımaktadır.
İstatistikler daha önce anlattığım gibi sp_updatestats ya da Update Statistics komutu ile güncellenebileceği gibi Auto_Update_Statistics veritabanı özelliğinin AKTİF yapılması ile de otomatik olarak güncellenebilir.
Auto_Update_Statistics veritabanı özelliği AKTİF yapıldığında, istatistiğe bağlı kolonlarda yapılacak toplam tablonun yaklaşık olarak %20 oranındaki satır güncellemesinden sonra istatistik ilk kullanılmak istendiği anda güncellenir.
Örneğin diyelim ki col1 kolonu üzerinde istatistik oluşturulmuş durumda. Tablodaki kayıt sayısının 1000 olduğunu düşünelim.
Bu durumda col1 kolonu için yapılacak yaklaşık olarak 200 güncelleme işleminden sonra istatistik kullanılmak istendiği ilk anda (örneğin select işleminde) otomatik olarak güncellenecektir.
Güncellenen satır sayısı, ilgili istatistiğin sysindexes.rowmodctr kolonunda tutulur.
Her güncellemeden sonra, eğer istatistik kolonu güncellendiyse ilgili istatistiğin sysindexes.rowmodctr kolonundaki değer 1 arttırılır.
Herhangi bir sorgu geldiğinde Query Plan kontrol edilirken kullanılan her istatistiğin sysindexes.
rowmodctr değerine bakılır ve eğer bu değer tablodaki toplam kayıt sayısının yaklaşık olarak %20’sini geçti ise istatistik güncellenir.
Şimdi bu durumu bir örnek ile gerçekleştirmeye çalışalım.
İlk olarak bir çalışma tablosu oluşturup içini rasgele değerler ile dolduralım.
Bir çalışma DB’si açılır */
use StatsDeneme GO
/*Auto_Create_Statistics parametresi on yapılır*/
alter database StatsDeneme set Auto_Update_Statistics ON
/*Bir çalışma tablosu create edilir.*/
if OBJECT_ID('StatsDeneme','U') is not null
drop table StatsDeneme
create table StatsDeneme(col1 int, col2 varchar(10), col3 char(8000))
GO
/*Çalışma tablosuna rasgele veriler basılır. */
declare @i
int=0
while @i<10000
begin
insert StatsDeneme
select @i,CAST(@i as varchar(10)),'a' + cast((@i % 10) as varchar(5))
set @i=@i+1
end
select * from [dbo].[StatsDeneme]
/* Çalışma tablosuna col3 kolonunun her değerine karşılık 1000 kayıt olacak durumda veriler dolduruldu.
Toplamda da 10 farklı col3 değeri olacak şekilde ayarlandı.
Sonuç itibarıyla StatsDeneme tablosundaki verilerin col3 kolonuna göre gruplanmış hali aşağıdaki gibi olacaktır.
Auto_Create_Statistics veritabanı özelliği AKTİF olduğu için tablonun ilgili kolonunu sorgulayarak istatistiğin oluşturulmasını sağlıyorum.
*/
select * from StatsDeneme where col3='a1'
/* Oluşan istatistiğin adını öğrenmek için sys.stats view’ini kullanıyorum. */
select * from sys.stats where object_id=object_id('StatsDeneme')
/*DBCC Show_Statistics ile istatistiğin en son güncellenme tarihini kontrol ediyorum.*/
dbcc show_statistics('StatsDeneme','_WA_Sys_00000003_108B795B')
/* İstatistiğin en son güncellenme tarihi saat 11:09. Daha sonraki kontrollerim için bu değeri kullanacağım. Şimdi tablonun col3 kolonundaki verileri güncelleyeceğim.
Her yaptığım güncelleme işlemi 1000 kaydı güncelleyecek. Her güncellemeden sonra dbcc show_statistics komutu ile istatistiğin güncellenme durumunu kontrol edeceğim.
Tekrar vurgulamak istiyorum. Update ve insert işleminden sonra istatistik direk olarak güncellenmez.
Ne zamanki istatistik kullanılmak istenir (örneğin bir sorgu işlemi), o zaman eğer ki değişen kayıt sayısı sınır değeri aştıysa istatistik güncellenir.
Dolayısıyla her kayıt güncellemesinden sonra istatistiği kullanmak adına tablonun ilgili kolonunu filtreleyecek şekilde bir sorgu çalıştıracağım.
Update işlemlerine başlıyorum.
-- a0 olan değerleri b0 olarak update ediyorum.
-- Bu işlem 1000 kaydı update edecek
*/
update StatsDeneme set col3='b0' where col3='a0'
/*sysindexes tablosunda 1000 kaydın update olduğu bilgisi loglanıyor */
select rowmodctr,* from sysindexes where name = '_WA_Sys_00000003_108B795B'
/* istatistiği kullanmak için select çekiyorum*/
select * from StatsDeneme where col3='a1'
/*istatistiğin update olup olmadığına bakıyorum*/
dbcc show_statistics('StatsDeneme','_WA_Sys_00000003_108B795B')
/*statistics güncellenme zamanı Jul 8 2014 7:38PM (şu anda 19.48)
sonuc: ROWMODCTR index üzerindeki yapılan değişiklik sayısını tutuyor.
sonra otomatik auto update statistikde toplam tablonun %20 kadar değişklik olduğunda bu sayıdan faydalanarak istatistikleri udapte ediyor
sysindexes tablosundaki ROWMODCTR= 1000 olarak değişti. Çünkü toplam 1000 kayda update geçtik
1000 kayıt daha güncelliyorum. Bu işlemle beraber toplam 2000 kaydı değiştirmiş olacağım.
Buradaki maksadımız, auto statistics özelliğinin, istatistiğe bağlı kolonlarda yapılacak TOPLAM TABLONUN YAKLAŞIK OLARAK %20 ORANINDAKİ SATIR GÜNCELLEMESİNDEN sonra istatistik ilk kullanılmak istendiği anda güncellenir
a1 olan değerleri b1 olarak update ediyorum.
Bu işlem 1000 kaydı daha update edecek
*/
update StatsDeneme set col3='b1' where col3='a1'
/*sysindexes tablosunda 1000+1000=2000 kaydın update olduğu bilgisi loglanıyor. */
select rowmodctr,* from sysindexes where name = '_WA_Sys_00000003_108B795B'
/* istatistiği kullanmak için select yapıyorum */
select * from StatsDeneme where col3='a1'
/*istatistiğin update olup olmadığına bakıyorum. */
dbcc show_statistics('StatsDeneme','_WA_Sys_00000003_108B795B')
/* statistics güncellenme zamanı HALEN Jul 8 2014 7:38PM (şu anda 19.56)
sonuc: Bu işlem sonunda toplamda 2000 satır güncellendi.
DBCC SHOW_STATISTICS sonucu gelen Updated kolonuna baktığımızda ise istatistiğin yine güncellenmediğini görüyoruz.
Ayrıca rowmodctr kolonunda değiştirilen kayıt sayısının 2000 olduğu bilgisi bulunmakta.
1000 kayıt daha güncelliyorum. Bu işlem sonunda toplamda 3000 kayıt değiştirilmiş olacak.
--a2 olan değerleri b2 olarak update ediyorum.
--Bu işlem 1000 kaydı daha update edecek */
update StatsDeneme set col3='b2' where col3='a2'
/*sysindexes tablosunda 1000+1000+1000=3000 kaydın update olduğu bilgisi loglanıyor. */
select rowmodctr,* from sysindexes where name = '_WA_Sys_00000003_108B795B'
/*istatistiği kullanmak için select çekiyorum */
select * from StatsDeneme where col3='a1'
/*istatistiğin update olup olmadığına bakıyorum. */
dbcc show_statistics('StatsDeneme','_WA_Sys_00000003_108B795B')
/*statistics otomatik güncellendi Jul 8 2014 8:02PM (şu anda 20.03)
Gördüğünüz gibi updated kolonundaki değer 08.02pm oldu, yani istatistik otomatik olarak güncellendi.
İşte bu otomatik istatistik güncelleme işleminin yapılmasını sağlayan veritabanı özelliği Auto_Update_Statistics’dir.
Aynı işlem Auto_Update_Statistics veritabanı özelliği PASİF iken yapılırsa istatistik otomatik olarak güncellenmeyecektir.
Bunu görmek için veritabanı özelliğini PASİF hale getirerek yukardaki örneği tekrarlayabilirsiniz.
İstatistiğin güncel olup olmamasına sysindexes.rowmodctr kolonundaki değere göre karar verilir demiştik.
İSTATİSTİK GÜNCELLENDİKTEN SONRA BU ROWMODCTR DEĞER 0 OLARAK SET EDİLİR. Bunu da kontrol edelim. */
select rowmodctr from sysindexes where name='_WA_Sys_00000003_108B795B'
/*sonuç: 0 istenen tablo üzerindeki statistik özelliğini ON/OFF yapar.
İstatistiğin güncel olması sorgunun tekrar derlenmesi anlamına geldiğini ve bu işleminde pahalı bir işlem olduğunu söylemiştik.
Eğer tablolarda çok fazla değişiklik olmasına rağmen verilerin dağılımında çok fazla değişiklik olmuyorsa istatistik boşuna güncellenecek dolayısıyla sorgu da boşuna tekrar derlenecektir.
Bu davranışta olan veritabanlarında Auto_Update_Statistics veritabanı özelliği PASİF yapılabilir. */
EXEC sp_autostats 'dbo.StatsDeneme','OFF'
/* Ayrıca sp_AutoStats ile illa tablodaki bütün istatistikler değil, istenen bir istatistik için de otomatik güncelleme özelliği kapatılabilir.
Bunun için ilgili sistem prosedürü aşağıdaki parametrelerle çalıştırılmalıdır. */
EXEC sp_autostats 'dbo.StatsDeneme', 'OFF'
/* Stats_1; Öneri: Genel parametrede ya da tablo bazında auto update statistics işlemi PASİF yapıldığında istatistiklerin elle güncellenmesi için zamanlanmış bir job tanımlamasında fayda vardır.
Örneğin Index bakımı işleminin içine istatistik güncelleme adımı eklenebilir. Şu notu da düşmekte fayda var.
Index rebuild işleminde rebuild olan index’e bağlı istatistikler otomatik olarak güncellenir.
Dolayısıyla rebuild edilen index’ler için istatistik güncellemeye gerek yoktur. Fakat reorganize işleminde istatistikler güncellenmez.
Bu istatistikler için güncelleme index bakımına ayrı bir adım olarak eklenmesi gerekmektedir. */
RecordBycunay
Record Date08-07-2014 20:25:43
Düzenle
Kopyala
Sil