Recent comments

None


İçerik Ara











Yasal Uyarı
Bu sitede sunulan tüm bilgi ve dökümanlar Turgay Sahtiyan tarafından yazılmaktadır. Yazıların kaynak göstermek şartıyla kullanılması serbesttir.

© Copyright 2009-2013
Takvim
<<  Haziran 2017  >>
PaSaÇaPeCuCuPa
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
Keywords

SQL Server’da Istatistik Kavramı adlı makalemde İstatistikler hakkında detaylı bir şekilde konuşmuştuk. Kısaca özet geçmek gerekirse; İ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.

[more]

Gene aynı makalede Auto_Update_Statistics database özelliğinin ne şekilde çalıştığından ve basic threshold değerinin kayıt sayısının %20+500 olduğundan bahsetmiştik. Yani örneğin 10.000 kayıttan oluşan bir tablomuz var ise ve bu tablodaki Col1 kolonu üzerine istatistik tanımlandıysa, Col1 kolonunu etkileyecek 2.500 güncelleme işleminden sonra istatistik ilk kullanılmak istendiği anda (örneğin select işleminde) otomatik olarak güncellenecektir.

İstatistikler doğru query plan oluşturulması için çok önemli olduğu için istatistiklerin olması kadar güncel olması da çok önem taşımaktadır. Bu yüzden best practice olarak Auto_Update_Statistics database özelliğinin açık olması önerilir. (Sharepoint gibi bazı database’lerde kapalı olması önerilmektedir) Fakat %20’lik threshold değeri oldukça fazla olduğundan çoğu durumda bu threshold değeri yakalanamamakta ve tablo çok fazla update görmesine rağmen istatistik update olmamaktadır. Örneğin 100.000.000 kayıttan oluşan bir hareket tablosundaki istatistiğin bu özellik sayesinde otomatik olarak update görmesi için yaklaşık 20.000.000 kaydın update olması gerekiyor ki reel hayatta böyle bir şey neredeyse mümkün değil.

İşte bu noktada karşımıza SQL Server 2008 R2 SP1 gelen 2371 Trace Flag’i çıkıyor. Bu trace flag aktif edildiğinde tablodaki kayıt sayısı arttıkça %20’lik threshold değeri daha erişilebilir seviyelere iniyor.

image

Kaynak : http://blogs.msdn.com/b/saponsqlserver/archive/2011/09/07/changes-to-automatic-update-statistics-in-sql-server-traceflag-2371.aspx

Yukarıdaki grafiği incelediğimizde tablodaki kayıt sayısı 25.000’ken %20’lik threshold geçerliyken, kayıt sayısı arttıkça %20’lik threshold aşağılara inmekte. Örneğin 100.000 kayıt sayısı için %10’lu değerlere, 1.000.000 kayıt için %3.2 gibi bir değere inmekte ki bu değerler artık yakalanabilir seviyelere gelmiş olmaktadır.

Özellikle çok büyük tablolarınız var ise (Örneğin SAP uygulaması, http://blogs.msdn.com/b/saponsqlserver/archive/2011/09/07/changes-to-automatic-update-statistics-in-sql-server-traceflag-2371.aspx) ve out of dated istatistiklerden dolayı performans sıkıntısı çektiğinizi düşünüyorsanız bu trace flag’i aktif hale getirmeyi düşünebilirsiniz.

Son olarak bir örnek yaparak trace flag’in davranışı görelim ve yazımıza son verelim.

--Bir calisma DB’si create ediyoruz
create database StatsDeneme
GO
use StatsDeneme
GO
--Auto_Create_Statistics ve Auto_Update_Statistics parametrelerini on yapiyoruz
alter database StatsDeneme set Auto_Create_Statistics ON
alter database StatsDeneme set Auto_Update_Statistics ON
--Bir calisma tablosu create ediyoruz
if OBJECT_ID('StatsDeneme','U') is not null
  drop table StatsDeneme
create table StatsDeneme(col1 int, col2 varchar(10), col3 varchar(5))
GO
--Calisma tablosuna rasgele 100.000 veri basiyoruz.
declare @i int=0
while @i<100000 begin
  insert StatsDeneme select @i,CAST(@i as varchar(10)),'a' + cast((@i % 10) as varchar(6))
  set @i=@i+1
end

--Istatistik olusturmak icin select sorgumuzu cekiyoruz
--Auto_Create_Statistics database ozelligi on oldugu icin
--	asagidaki sorgu sonucu col3 kolonu icin istatistik olusacaktir
select * from StatsDeneme where col3='a1'

--Istatistigin son guncellenme zamanina bakiyoruz
select object_name(object_id),name as StatsName,STATS_DATE(object_id,stats_id) 
from sys.stats
where object_name(object_id) = 'StatsDeneme'

--Trace Flag'i aktif etmeden 10.000 kaydi update ediyoruz (%10)
update top(10000) StatsDeneme set Col3 = 'xx' 

--Auto_Update_Statistics ozelligini tetiklemek icin select sorgusunu tekrar cekiyoruz
select * from StatsDeneme where col3='a1'

--Istatistigin son guncellenme zamanina tekrar bakiyoruz ve 
--	daha %20+500'luk threshold dolmadigi icin update olmadigini goruyoruz
select object_name(object_id),name as StatsName,STATS_DATE(object_id,stats_id) 
from sys.stats
where object_name(object_id) = 'StatsDeneme'

--10.500 kaydi daha update ediyoruz ve threshold'u yakaliyoruz (%20%500)
update top(10500) StatsDeneme set Col3 = 'xx' 

--Auto_Update_Statistics ozelligini tetiklemek icin select sorgusunu tekrar cekiyoruz
select * from StatsDeneme where col3='a1'

--Istatistigin son guncellenme zamanina tekrar bakiyoruz ve istatistigin update oldugunu goruyoruz
select object_name(object_id),name as StatsName,STATS_DATE(object_id,stats_id) 
from sys.stats
where object_name(object_id) = 'StatsDeneme'

--Dolayisiyla 2371 trace flag'ini kullanmadan threshold degerimiz %20+500
--Simdi ayni islemleri 2371 trace flag'ini aktif ederek tekrar yapalim

--Trace Flag'i aktif ediyoruz 
DBCC TraceOn (2371)

--Not:Trace flag'i bu sekilde aktif etmektense trace flag startup parametrelerine konularak 
--	SQL Server her acildiginda trace flag otomatik olarak aktif ettirilebilir)

--10.000 kaydi update ediyoruz (%10)
update top(10000) StatsDeneme set Col3 = 'yy' 

--Auto_Update_Statistics ozelligini tetiklemek icin select sorgusunu tekrar cekiyoruz
select * from StatsDeneme where col3='a1'

--Istatistigin update oldugunu goruyoruz. 
--%10'luk kisim update olmasına ragmen istatistigin update olma nedeni 2371 trace flag'ini aktif etmis olmamiz
select object_name(object_id),name as StatsName,STATS_DATE(object_id,stats_id) 
from sys.stats
where object_name(object_id) = 'StatsDeneme'

--calisma database'ini drop ediyoruz
use master
go
drop database StatsDeneme
Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


İstatistiklerin Query Plan oluşturulması aşamasında üstlendikleri rolü SQL Server’da İstatistik Kavramı adlı makalemde detaylı olarak incelemiştik. Güncel olmayan istatistiklerin yanlış Query Plan’lar oluşturulmasına dolayısıyla performans sıkıntısına sebebiyet verdiğini belirtmiştik. Bu yüzden Auto_Update_Statistics gibi istatistiklerin otomatik olarak güncellenmesini sağlayan parametrelerin aktif yapılmasının çoğu ortam için oldukça önemli olduğunun özellikle üzerinde durmuştuk.

İstatistikler güncellendikten sonra sorgular Recompile edilir. (Sorguların ReCompile edilme nedenlerine şu makaleden erişebilirsiniz.) Fakat eğer tablo update görmesine rağmen istatistiğin dağılımında çok fazla değişiklik olmuyorsa bu durumda boşu boşuna istatistiği update etmeye ve sorgunun ReCompile edilmesini tetiklemeye gerek yoktur.

Bu makalemde Index create edilirken verilen STATISTICS_NORECOMPUTE parametresi ile create edilen Index’e bağlı istatistiğin otomatik olarak update edilmesinin nasıl engellendiğini görüyor olacağız.

[more]

STATISTICS_NORECOMPUTE parametresinin varsayılan değeri OFF’dur. Yani Auto_Update_Statistics parametresi ON durumdaysa ilgili istatistiğe bağlı tabloda %20+500 kayıt update olduğunda istatistik update olacaktır.

Eğer Index create edilirken STATISTICS_NORECOMPUTE özelliği OFF yapılırsa istatistik otomatik olarak update olmayacaktır.

Şimdi bu durumu gerçekleştirmek için bir çalışma tablosu oluşturup bu tablo üzerinde birbirinin aynısı olan 2 Index create edeceğiz. Index’lerin ilkini STATISTICS_NORECOMPUTE=OFF olarak create ederken, ikincisini ON olarak create edeceğiz. Daha sonra tabloda belirli bir sayıdaki kaydı update edip istatistiklerin otomatik olarak update olup olmadığını gözlemleyeceğiz.

Üzerinde çalışacağımız çalışma tablosunu hazırlayalım.

Create Database DBTest
GO
ALTER DATABASE [DBTest] SET AUTO_UPDATE_STATISTICS ON
GO
Use DBTest
GO
Create Table tbl_Test (Col1 int identity(1,1), Col2 varchar(10))
GO
Insert tbl_Test
	select 'a'
GO 10000

 

2 index create edelim. İlkini STATISTICS_NORECOMPUTE=OFF ikincisini ON olarak create ediyoruz.

--İlk index STATISTICS_NORECOMPUTE=OFF 
Create NonClustered Index IX_1 on tbl_Test(Col2)
	WITH (STATISTICS_NORECOMPUTE=OFF)
GO

--İkinci index STATISTICS_NORECOMPUTE=ON 
Create NonClustered Index IX_2 on tbl_Test(Col2)
	WITH (STATISTICS_NORECOMPUTE=ON)
GO

 

İstatistiklerin şu anki son güncellenme tarihlerine bakalım.

--İstatistiklerin şu anki güncellenme tarihlerine bakalım
select name, STATS_DATE(object_id,stats_id) as last_update_date
from sys.stats s
where s.object_id = object_id('dbo.tbl_Test')

 

image

Şimdi tablodaki kayıtların %20+500’ünü update ederek istatistiklerin otomatik güncellenmesini sağlayalım.

--Tablonun %20+500 kaydını update edelim
update top (2500) tbl_Test set Col2='b'

--İstatistikleri kullanarak otomatik güncellenmelerini tetikleyelim.
select * from tbl_Test With (INDEX=IX_1) where Col2='x' 
GO
select * from tbl_Test With (INDEX=IX_2) where Col2='x' 
GO

 

İstatistiklerin güncellenme tarihlerine tekrar bakalım.

--İstatistiklerin güncellenme tarihine tekrar bakalım
select name, STATS_DATE(object_id,stats_id) as last_update_date
from sys.stats s
where s.object_id = object_id('dbo.tbl_Test')

 

image

Gördüğünüz gibi NORECOMPUTE özelliği OFF olan istatistik güncellenmişken ON olan istatistik güncellenmedi.

 

Tablodaki kayıtlar güncellenmesine rağmen istatistiğin dağılımında çok fazla değişiklik olmuyorsa STATISTICS_NORECOMPUTE özelliğini ON yapmayı düşünebilirsiniz. Bu şekilde istatistik boşu boşuna güncellenmeyecek dolayısıyla da sorgulara ReCompile olmayacaktır.

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


23.11.2011 tarihinde gerçekleştirmiş olduğum SQL Server Performans İpuçları başlıklık webcast’imin videosuna ve diğer dosyalarına aşağıda erişebilirsiniz.

 

 

 

Scriptler

 

Not : Webcast videosu yakın bir zamanda www.cozumpark.com portalinde de yayınlanacaktır.

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


23 Kasım Çarşamba günü yapacağım webcast’in duyurusunu yapmak istiyorum.

SQL Server Performance Tuning İpuçları başlıklı webcast’im 23.11.2011 tarihinde 21:00-22:00 saatleri arasında gerçekleşecek.

Aşağıdaki url’i kullanarak vereceğim bu webcast’e katılabilirsiniz.

https://www.livemeeting.com/cc/mvp/join?id=6N4JP9&role=attend&pw=2NM%7E%60JK%7Bt

Webcast süresince şu performans ipuçları üzerinde duracağız.

  1. FILLFACTOR – PAD_INDEX
  2. Filtered Index
  3. Indexed View
  4. Filtered Index vs Indexed View
  5. NC Index’lerde Included Kolon Kullanımı
  6. Index Seek : PT Bitti mi?
  7. Where Bloğunda Case Kullanımı
  8. Where Bloğunda Collate Kullanımı
  9. Eksik Index (Missing Index) Analizi
  10. Index Maintenance
  11. İstatistiğin Güncel Olmasının Önemi
  12. Optimize For Ad Hoc Workloads
  13. Instant File Initialization
  14. Veritabanı Dosya Büyümeleri

 

Not:Katılım url’i webcast başlamadan yarım saat önce aktif hale gelecektir.

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Keskin bir ifade oldu farkındayım :) O yüzden cümlenin başına “çok zorda kalmadıkça diye” ekleyelim. Kullanmayın deme sebebim ise where bloğunda case kullanımı, istatistikler üzerinden estimated rows hesabı yapılırken yanlış hesaplamalar yapılmasına dolayısıyla da estimate edilecek kayıt sayısının doğru tahminlenememesi anlamına gelmektedir. Bu durumda da Query Plan sağlıklı bir şekilde oluşturulamayacak ve gereksiz IO yapılmasından dolayı performans sıkıntısı ortaya çıkacaktır. Bugünkü yazımda bahsettiğim bu konuyu örnekler ile görüyor olacağız.

[more]

Örneklerimde AdventureWork.Person.Address tablosunu kullanıp City kolonu üzerinden sorgular çekeceğim. Bu yüzden ilk olarak City kolonu üzerine bir NonClustered Index oluşturuyorum.

IF  not exists (select * from sys.indexes where object_id = OBJECT_ID('Person.Address') AND name = 'IX_1')
  create nonclustered index IX_City on Person.Address
	(City)

 

Person.Address tablosuna çekeceğim sorgularda City bilgisi olarak Bothell. Normal şartlarda Bothell için çekilen sorguların Query Planı şu şekilde olmakta.

1

Şimdi where bloğunda case anahtar kelimesi içeren şöyle bir sorgu yazıyorum.

declare @val1 varchar(10)=NULL
declare @val2 varchar(10)='Bothell'
select * from Person.Address 
	where City = (case when @val1 is null then @val2
					else @val1 end)

 

Sorguda da gördüğünüz gibi eğer @val1 değişkeni null değil ise city bilgisi olarak bu değişken, eğer null ise city bilgisi olarak @val2 değişkeni kullanılacak. Bu durumda yukarıdaki sorguyu çalıştırdığımda “Bothell” için çalıştırmış olacağım.

2

Bothell için normal şartlarda Index Seek yaptığını daha önce görmüştük. Oysaki bu sorguda case kullandığım için artık Clustered Index Scan yapılmakta.

Bunun nedeni ise Estimated Rows kısmında gördüğümüz istatistikler üzerinden hesaplanan “tahmini dönecek kayıt sayısı” bilgisinin normalden çok olmasıdır. Aşağıdaki resimde 2 sorgu için tahminlenen kayıt sayılarını görebilirsiniz.

3

Bu yüzden ilk sorgu için Index Seek yapılmasına karar verilirken, ikinci sorguda dönecek kayıt sayısı olması gerekenden fazla yani yanlış hesaplandığı için Clustered Index Scan yapılmasına karar veriliyor.

İşte bu sebepten dolayı sorguların where bloğunda case kullanımından olabildiğince kaçınmakta fayda olduğunu söyleyebilirim.

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Mart 2011’de yayınladığım SQL Server’da Index Kavramı başlıklı makalemden sonra bugün de performans iyileştirmenin bir diğer büyük adımı olan SQL Server’da İstatistis (Statistics) Kavramı üzerine yazılmış detaylı makalemi paylaşıyorum.

Bu makale, SQL Server’da istatistiklerin kullanım amacını,faydalarını ve güncel olmalarının önemini sorguladıktan sonra, istatistiklerinin içeriğinin incelenmesi ve istatistiklerin otomatik oluşturulma ve güncellenme parametrelerinin ve bu parametrelerin best practice’lerinin neler oldukları üzerinde duracaktır.

[more]

Makaledeki ana başlıklar şu şekildedir.

  • İstatistik (Stat) Nedir?
  • DBCC SHOW_STATISTICS Komutu ile İstatistik İçeriğini Görüntülemek
  • İstatistiklerin Güncel Olmasının Önemi
  • İstatistiklerin Otomatik Oluşturulma ve Güncellenme Parametreleri
    • Auto_Create_Statistics
    • Auto_Update_Statistics
    • Auto_Update_Statistics_Async
  • SQL Server Profiler ile İstatistik Oluşma ve Güncellenme İşlemlerini İzlemek
  • Sonuç

Makale çok uzun olduğu için word formatında yayınlayacağım. Dosyayı buradan indirebilirsiniz.

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Stored Procedure(SP) ilk çalıştırıldığı zaman istatistikler göz önüne alınarak Query Optimizer tarafından en optimum Query Plan oluşturulur ve daha sonra kullanılmak üzere Plan Cache’e konulur. Aynı SP farklı bir zamanda tekrar çalıştırıldığında Cache’deki plan’ın geçerliliği kontrol edilir ve eğer plan geçerli yani güncel ise tekrar Query Plan oluşturulmak için zaman harcanmayıp plan Cache’den çağırılır ve kullanılır.

Query Plan oluşturma işlemi bazı durumlarda çok fazla CPU kaynağı tükettiği için bu şekilde bir cache’lenme mekanizması kullanılır. Fakat bazı durumlarda cache’lenen plan güncelliğini yitirmiş olabilir. Örneğin SP içinde geçen bir tabloda plan cache’lendikten sonra çok fazla data değişimi olduysa bu durumda istatistikler güncelliğini yitirecek dolayısıyla da cache’lenen plan güncelliğini yitirecektir. Ya da SP’nin içinde geçen tablolarda index ekleme,silme gibi DDL (Data Definition Language) değişiklikleri yapılırsa yine cache’lenen plan güncelliğini yitirmiş olacaktır. Böyle bir durumda SP’nin yeniden derlenip yeni bir Query Plan’ın oluşturulması gerekmektedir. İşte bu duruma ReCompilation denilmektedir.

[more]

Yukarıda anlattığım şekilde istatistik değişimi ya da DDL değişikliği gibi işlemler sonucunda recompilation gerçekleşebileceği gibi SP oluşturulurken yazılan “WITH RECOMPILE” anahtar kelimesi SP’nin her çalışmasın recompile edilmesi sağlanabilir. Örneğin aşağıdaki şekilde oluşturulan SP her çağırılışında tekrar derlenecektir.

CREATE PROC dbo.sp_1
WITH RECOMPILE
AS
	SELECT * FROM Tbl1

 

WITH RECOMPILE anahtar kelimesi ile oluşturulan SP’lerin planları Plan Cache’de saklanmaz, SP her çalıştırıldığında tekrar oluşturulur. Bu seçenek, SP’nin aldığı parametrelere göre değişik Query Plan’lar oluşturduğu durumda kullanılabilir. Örneğin SP “a” parametresi ile çağırıldığında index scan, “b” parametresi ile çağırıldığında index seek yapıyorsa yani gönderilen parametreye göre Query Plan’ı değişiyorsa WITH RECOMPILE anahtar kelimesinin kullanılması mantıklı olacaktır.

WITH RECOMPILE ile SP’nin tamamı recompile edilir. SP’nin tamamının değilde içinde geçen bazı sorgu parçacıklarının yeniden derlenmesi isteniyorsa sorguların WITH RECOMPILE anahtar kelimesi ile yazılması gerekir.

SP’ler aşağıdaki durumlardan herhangi biri oluştuğunda recompile olacak yani yeniden derlenecektir.

  • Schema değiştiğinde
  • İstatistik değiştiğinde
  • SP’nin oluşturulma kodunda “With Recompile” anahtar kelimesi kullanıldığında
  • Set opsiyonları değiştiğinde
  • Temp table değiştiğinde
  • Remote rowset değiştiğinde
  • For browse perms değiştiğinde
  • Query notification environment değiştiğinde
  • Partition view değiştiğinde
  • Cursor seçenekleri değiştiğinde
  • Statement’ta Recompile seçeneği kullanıldığında

SP’ler yukarıda anlattığım şekilde recompile olabileceği gibi recompile olması için elle de tetiklenebilir.

EXEC sp_recompile N'dbo.sp_1'

 

Yukarıdaki kod vasıtasıyla sp_1 SP’sine recompile olması için bir işaret konulur. Bu SP bir dahaki sefer çalıştırılmak istendiğinde yeniden derlenecektir. sp_recompile sistem prosedürüne parametre olarak tablo ya da view de verilebilir. Bu durumda tabloya referans olan SP’ler recompile olacaktır.

SQL Server 2005’ten önceki sürümlerde SP recompilation işlemi SP’nin tamamında gerçekleştirilmekteydi. Yani örneğin SP’nin içinde bulunan bir sorgunun recompile edilmesi gerektiğinde SP’nin tamamı recompile edilmekteydi. 2005’ten sonraki versiyonlarda ise artık sadece recompile edilmesi gereken sorgu recompile edilmektedir. Bu şekilde çok büyük SP’lerde bir sorgu için SP’nin tamamı recompile edilmektense sadece ilgili kısım recompile edilebilmektedir. Bu da performans artışı anlamına gelmektedir.

Ayrıca SP recompile edilirken blocking’lere sebebiyet vermektedir. Bu yüzden çok fazla recompile olan SP ya da sorguların analiz edilmesinde fayda vardır.

ReCompilation Olaylarının İzlenmesi

SQL Server Profiler - SQL:StmtRecompile - SP:Recompile

Recompilation olayları SQL Server Profiler ile izlenebilmektedir. Bunun için kullanılan olaylar SQL:StmtRecompile ve SP:Recompile olaylarıdır.

SP:Recompile olayı ile recompile olan SP’ler izlenebilir. SQL:StmtRecompile olayı ile ise recompile olan sorgular izlenebilir. Daha önce bahsettiğim gibi SQL Server 2005 sürümünden sonra bir sorgunun recompile edilmesi gerektiğinde SP’nin tamamı değil sadece ilgili sorgu recompile edilmektedir. Dolayısıyla recompile işlemlerini izlemek için SP:Recompile yerine SQL:StmtRecompile olayının kullanılması daha mantıklı olacaktır.

Windows Performance Counter - SQL Re-Compilation/sec

Recomplation işlemleri windows performance counter’lar ile de izlenebilmektedir. Bunun için kullanılan performance counter SQL Re-Compilation/sec performance counter’ıdır. Genelde bu counter’ın toplam batch request’in %10’undan az olması beklenir. Bu değerden daha yüksek değerlerde, recompile olan sorgu veya SP’lerin detaylı incelenmesinde, neden recompile olduklarının analiz edilmesinde fayda vardır. Çünkü tekrar etmek gerekirse compilation işlemi CPU kaynaklarının çok fazla tüketilmesine sebep olabilir.

Activity Monitor

Recompilation olan SP ya da sorguların izlenmesi için kullanılan bir diğer araç ise SQL Server 2008 ile gelen Activity Monitor ekranıdır. Bu ekranda bulunan Recent Expensive Queries kısmındaki Plan Count kolonu ilgili SP’nin ya da sorgunun kaç kez recompile edildiğini göstermektedir.

1

Sys.dm_exec_query_stats – plan_generation_num

Recompilation’ları izlemenin bir diğer yolu da sys.dm_exec_query_stats DMV’sidir. Bu DMV’de bulunan plan_generation_num kolonu ile ilgili sorgunun kaç kez recompile edildiği bulunabilir.

select
	st.text,
	qs.sql_handle,
	qs.plan_generation_num,
	qs.creation_time,
	qs.execution_count,
	st.dbid,
	st.objectid
from sys.dm_exec_query_stats qs
cross apply sys.dm_exec_sql_text(sql_handle) st
where qs.plan_generation_num>1 and st.objectid is not null
order by qs.plan_generation_num desc

 

2

Ayrıca gene bu DMV sonucunda gelen creation_time kolonu vasıtasıyla sorgunun en son ne zaman recompile edildiği bilgisine ulaşılabilmektedir.

Sonuç

SP’nin yeniden derlenmesi bazı durumlarda CPU kaynaklarının çok fazla kullanılmasına neden olabilir. Ayrıca yeniden derleme işlemi sırasında blocking’ler oluşabilir. Bu yüzden recompilation olayları izlenmeli, çok fazla recompile olan sorgu ya da SP’lerin recompile nedenleri analiz edilmelidir.

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan