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
<<  Ekim 2017  >>
PaSaÇaPeCuCuPa
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345
Keywords

Her ne kadar arzu edilen durum, yazılım geliştiricilerin ve analistlerin production ortamında sorgu çalıştırmaması olsa da, bazı durumlarda kayıtların doğruluğunu ve işlemlerin sonuçlarını canlı ortamda görmek için bu kullanıcıların production ortamında işlem yapması gerekebilir.

Yapılan bu işlemler bazı durumlarda yanlış kod yazımından dolayı çok uzun sürüp gereksiz kaynak tüketimine neden olabilir, bu da sistemin performansına etkileyebilir.

Bugünkü yazımda bir SP vasıtasıyla, belirlediğimiz süreden daha uzun süredir çalışan session’ları otomatik olarak nasıl kill edebileceğimizi görüyor olacağız. Ayrıca ilgili session’ları kill etmeden önce çalıştırdıkları sorguları öğrenip, kill edilme işleminin detaylarını log tablosunda loglayacağız.

[more]

Kill edilme işlemlerini loglayacağımız tablo şu şekilde.

USE AdventureWorks2008R2

CREATE TABLE [dbo].[Killed_Long_Running_Users_Sessions](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[login_name] [varchar](50) NULL,
	[session_id] [int] NULL,
	[Command] [varchar](100) NULL,
	[database_id] [int] NULL,
	[start_time] [datetime] NULL,
	[total_elapsed_time] [int] NULL,
	[logical_reads] [int] NULL,
	[killing_login_name] [varchar](50) NULL,
	[killing_time] [datetime] NULL,
	[Message] [varchar](255) NULL,
	[sql_text] [varchar](max) NULL,
	[statement_text] [varchar](max) NULL,
 CONSTRAINT [PK_Killed_Users_Sessions] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)
) ON [PRIMARY]

 

Bizim belirlediğimiz süreden daha uzun süredir çalışan session’ları bulup kill edecek SP ise şu şekilde.

USE AdventureWorks2008R2
GO

CREATE PROC [dbo].[Kill_Long_Running_Users_Sessions] (@Threshold_Second int, @login_name_prefix as varchar(10))
AS

declare @str varchar(max)

declare ACur cursor for
select es.login_name
	,er.session_id
	,er.command
	,er.database_id
	,er.start_time
	,er.total_elapsed_time
	,er.logical_reads
	,st.text as sql_text
	,SUBSTRING(st.text, (er.statement_start_offset/2)+1, 
			((CASE er.statement_end_offset
			  WHEN -1 THEN DATALENGTH(st.text)
			 ELSE er.statement_end_offset
			 END - er.statement_start_offset)/2) + 1) AS statement_text	
from sys.dm_exec_requests er
cross apply sys.dm_exec_sql_text(er.sql_handle) st
join sys.dm_exec_sessions es on es.session_id=er.session_id
where er.session_id>50
	and (es.login_name like @login_name_prefix+'%' 
	--kill edilmesini istemediğimiz loginname'leri belirtiyoruz
	and es.login_name  NOT IN ('sa','adminturgay')) 
	
	and er.total_elapsed_time>(@Threshold_Second*1000)
	
declare @login_name varchar(50),@session_id int,@Command varchar(100),@database_id int
	,@start_time datetime,@total_elapsed_time int,@logical_reads int,@sql_text varchar(max),@statement_text varchar(max)
open ACur
fetch from ACur into @login_name,@session_id,@Command,@database_id,@start_time,@total_elapsed_time,@logical_reads,@sql_text,@statement_text
while @@FETCH_STATUS=0
begin
	select @str = 'kill ' + cast(@session_id as varchar(10))
	begin try
		exec(@str)
		
		insert dbo.Killed_Long_Running_Users_Sessions (login_name,session_id,Command,database_id,start_time,total_elapsed_time,logical_reads,killing_login_name,killing_time,Message,sql_text,statement_text)
		values (@login_name,@session_id,@Command,@database_id,@start_time,@total_elapsed_time,@logical_reads,suser_name(),getdate(),'Session Killed',@sql_text,@statement_text)
	end try
	begin catch
		insert dbo.Killed_Long_Running_Users_Sessions (login_name,session_id,Command,database_id,start_time,total_elapsed_time,logical_reads,killing_login_name,killing_time,Message,sql_text,statement_text)
		values (@login_name,@session_id,@Command,@database_id,@start_time,@total_elapsed_time,@logical_reads,suser_name(),getdate(),'An Error Accured When Killing Session',@sql_text,@statement_text)
	end catch
	fetch next from ACur into @login_name,@session_id,@Command,@database_id,@start_time,@total_elapsed_time,@logical_reads,@sql_text,@statement_text
end
close ACur
deallocate Acur

 

SP 2 tane parametre almakta.

  • @Threshold_Second : Kaç saniyeden uzun süren session’ların kill edilmesini istediğimizi bu parametre ile belirtebiliriz.
  • @login_name_prefix : Eğer developer ve analistler bir domain grubunun üyesi ise ve application user’lar sql authentication ile bağlanıyorlar ise bu parametreyi kullanabiliriz. Örneğin loginname’i “MS/” ile başlayan kullanıcıların session’ları kill edilsin şeklinde bir genelleme yapabiliriz. Eğer böyle bir genelleme yok ise bu parametreyi boş geçebiliriz.

Ayrıca kodun içinde istisna olarak kullanıcı adı tanımlayabilirsiniz. Bu kısım ile kill edilmesini istemediğiniz “sa” ya da buna benzer kullanıcı adları var ise bu kullanıcı adlarını bu işlemin dışında bırakabilirsiniz.

Şimdi bir örnek yapalım. Aşağıdaki kod bloğunu “sa” olmayan bir kullanıcı ile çalıştıralım.

waitfor delay '01:00:00'
select * from sys.tables

 

Şimdi de 60 sn’den daha uzun süredir devam eden sorguları kill edelim.

exec dbo.Kill_Long_Running_Users_Sessions 60,''

 

Ve son olarak log tablosunda kill olan session ile ilgili detaylara bakalım.

select * from dbo.Killed_Long_Running_Users_Sessions

 

1

2

Bu SP’yi bir job’ın içine tanımlayıp örneğin 1 dakikada 1 çalıştırabilirsiniz. Bu şekilde developer ya da analistler gibi kullanıcılar tarafından bilinçsizci yazılmış sunucunun performansını etkileyecek uzun süren sorguları otomatik olarak kill edebilirsiniz.

 

İ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


SQL Server 2011 Denali’nin ilk çıkan CTP’sinde anons edilen ColumnStore Index tipi özellikle DWH sistemleri için heyecan yaratmıştı. Bazı sorgularda 16 kata kadar iyileştirme sağladığı söylenen ColumnStore Index için ben de şu makaleyi yazmıştım.

CTP1 versiyonunda ColumnStore Index kullanımı olmadığı için sadece duyduklarımızla yetinirken CTP3’ün çıkmasıyla beraber artık ColumnStore Index’i denemeye başlayabiliriz.

[more]

Daha önce yazdığım makalede ColumnStore Index’in ana mantığının kayıtları page’lerde satır bazlı değil sütun bazlı saklaması olduğunu belirtip avantajlarını şu şekilde sıralamıştım.

  • Sadece istenen kolon ile ilgili page’ler disk’ten okunabilir. Bu durumda gereksiz kolonların okunması engellenmiş olur.Bu da daha az page okunması yani performans artışı manasına gelmektedir.
  • Page’lerin içinde aynı kolona ait bilgiler tutulduğu ve bu bilgilerin birbirinin aynısının olma ihtimali yüksek olduğu için columnstore page’ler çok iyi sıkıştırılabilir. Bu da gene diskten daha az datanın okunması anlamına gelmektedir.
  • Daha az page memory’e alındığı için buffer cache hit ratio performance counter’ı yani istenen bilgilerin memory’den karşılanması counter’ı çok artacaktır. Bu da performans artışına delalettir.

Şimdi isterseniz gelin bir örnek yaparak bu avantajları tek tek görmeye çalışalım.

Örneğimiz için ilk olarak bir çalışma tablosu create edip içine 1.000.000 kayıt basıyorum. Kayıtları mod 100’den geçirerek 100 farklı kayıdın oluşmasını sağlıyorum ki tablomda benzer kayıtlar olsun dolayısıyla ColumnStore index’in özelliklerinden faydalanabileyim.

Create Table DenemeTbl (Col1 int, Col2 char(10), Col3 char(20), Col4 char(15), Col5 char(20))
GO

SET NOCOUNT ON

declare @i int=0
while @i<1000000 begin
  insert DenemeTbl
    select @i
	  ,'turgay'+cast(@i%100 as varchar(2))
	  ,'sahtiyan'+cast(@i%100 as varchar(2))
	  ,'SQLServerDBA'+cast(@i%100 as varchar(2))
	  ,'555 55 55 '+cast(@i%100 as varchar(2))
  set @i=@i+1
end

 

Şimdi Col1 için Clustered Index ve Col2,Col3,Col4,Col5'ten oluşan composite bir NonClustered Index oluşturuyorum. Bu oluşturduğum NonClustered Index’i ColumnStore Index ile karşılaştırma yapmak için kullanacağım.

create clustered index CIX_1 on DenemeTbl (Col1)
GO

create nonclustered index IX_NormalIndex on DenemeTbl (Col2, Col3, Col4, Col5)
GO

 

Şimdi yukarıdaki NonClustered Index ile aynı kolonlar üzerine bir ColumnStore Index oluşturuyorum. İşlemi hem TSQL kod ile hem de SSMS ile yapabilirim.

SSMS ile arayüzden yapmak için tablonun detayında bulunan Index yazısına sağ tıklayıp Non-Clustered ColumnStore Index yazısını seçiyorum.

1

Gelen Index tanımlama ekranında Index için bir isim belirleyip daha sonra Add butonu vasıtasıyla Index’in kolonlarını seçiyorum.

2

OK’e basarak ColumnStore Index’i create ediyorum.

Aynı işlemi aşağıdaki TSQL komutunu kullanarak ta yapabilirim.

create nonclustered COLUMNSTORE index IX_ColumnsStoreIndex on DenemeTbl (Col2, Col3, Col4, Col5)
GO

 

Sonuç itibarıyla tablomda şu index’ler olacak.

Index Type IndexName
Clustered Index CIX_1
NonClustered Index IX_NormalIndex
NonClustered ColumnStore Index IX_ColumnsStoreIndex

 

Index listesine tablonun altındaki Index kısmından da ulaşabilirim.

3

Kayıtlar Page’lerde Satır Bazlı Değil Kolon Bazlı Tutulur

ColumnStore Index’in mantığı, klasik index’lerin aksine, kayıtların page’lerin içinde satır bazlı değil kolon bazlı olarak tutulmasıdır.

Her 2 index’in leaf level page’lerini incelediğimizde;

Normal NonClustered Index Leaf Level Page Örneği ;

4

Kayıtların satır bazında tutulduğunu görüyoruz.

ColumnStore Index’in leaf level page’ine baktığımızda ise kayıtların kolon bazında sıkıştırılarak tutulduğu için LOB olarak tutulduğunu görüyoruz.

5

ColumnStore Index Daha Az Page’ten Oluşur

ColumnStore Index, kayıtları kolon bazında tuttuğu ve bu kolondaki bilgilerin birbirinin aynısının olma ihtimali yüksek olduğu için ColumnStore page’ler çok iyi sıkıştırılabilir. Bu da Index’in daha az page’ten oluşması anlamına gelir.

Şimdi 2 index arasındaki boyut ve page sayısı farkına bakıp yukarıdaki savı doğrulayalım.

select i.name as IndexName
	   ,reserved_page_count as PageCount
	   ,reserved_page_count*8 as IndexSize_KB
from sys.dm_db_partition_stats ps
left join sys.indexes i on i.object_id = ps.object_id and i.index_id = ps.index_id
where ps.object_id=OBJECT_ID('DenemeTbl') and ps.index_id>1

 

6

Gördüğünüz gibi Normal NonClustered Index 9477 page’ten oluşurken aynı kolonlar üzerine oluşturulmuş ColumnStore Index ise sadece 354 page’ten oluşmakta.

ColumnStore Index Daha Performanslı Çalışır

ColumnStore Index,muadili Normal NonClustered Index’e oranla daha az page’ten oluştuğu ve ayrıca tek bir kolonun sorgulanmak istendiği durumda sadece ilgili kolonun page’lerini getirebilme özelliklerinden dolayı daha performanslı çalışır. Daha önceki makalemde bu performans artışının 16 kata kadar çıkabileceğini belirtmiştik. Şimdi bunun denemesi gelin bir de biz yapalım.

Yapacağım denemede IO istatistiğini açarak her 2 index’in logical read değerlerini karşılaştıracağım.

SET STATISTICS IO ON
GO

--Cache'de bulunan plan'ları silelim
DBCC FREEPROCCACHE
GO
--Memory'de bulunan page'leri silerek 
--page'lerin diskten okunmasını sağlayalım.
DBCC DROPCLEANBUFFERS
GO

select Col3 
from dbo.DenemeTbl with (Index = IX_NormalIndex)
where Col2 = 'Turgay15' 
GO

--Cache'de bulunan plan'ları silelim
DBCC FREEPROCCACHE
GO
--Memory'de bulunan page'leri silerek 
--page'lerin diskten okunmasını sağlayalım.
DBCC DROPCLEANBUFFERS
GO

select Col3 
from dbo.DenemeTbl with (Index = IX_ColumnsStoreIndex)
where Col2 = 'Turgay15' 
GO

 

7

Resimde de gördüğünüz gibi Normal NonClusteredIndex kullanılarak 98 page’in okunması gerekirken aynı sorgu ColumnStore Index kullanılarak 32 page okunarak tamamlanabiliyor.

Bu örneğimizde tabloda çok fazla kayıt olmadığı için performans artışı 3 kat seviyelerinde kaldı. Büyük DWH sistemlerinde performans artışı çok daha fazla olabilecektir.

ColumnStore Index İçeren Tablolarda Insert, Update, Delete Yapılamaz

ColumnStore Index’lerin en büyük eksisi bu tip index’leri içeren tablolarda insert,update,delete işlemleri yapılamamasıdır. ColumnStore index içeren tabloda bu tarz bir işlem yapılmak istendiğinde şu tarz bir hata mesajı alınacaktır.

insert DenemeTbl
	Select 1000001, 'Turgay', 'Sahtiyan', 'SQLServerDBA', '555 55 55'
GO

update DenemeTbl
	set Col2 = 'Turgay'
	where Col1 = 1
GO

delete from DenemeTbl where Col1=1
GO

 

Msg 35330, Level 15, State 1, Line 1
INSERT statement failed because data cannot be updated in a table with a columnstore index. Consider disabling the columnstore index before issuing the INSERT statement, then rebuilding the columnstore index after INSERT is complete.


Msg 35330, Level 15, State 1, Line 2 UPDATE statement failed because data cannot be updated in a table with a columnstore index. Consider disabling the columnstore index before issuing the UPDATE statement, then rebuilding the columnstore index after UPDATE is complete.


Msg 35330, Level 15, State 1, Line 2 DELETE statement failed because data cannot be updated in a table with a columnstore index. Consider disabling the columnstore index before issuing the DELETE statement, then rebuilding the columnstore index after DELETE is complete.

8

Hata mesajında da gördüğünüz gibi insert,delete,update işleminden önce ColumnStore index disable edilmeli, işlem bitiminde de rebuild edilmelidir.

alter index IX_ColumnsStoreIndex on dbo.DenemeTbl disable
GO

insert DenemeTbl
	Select 1000001, 'Turgay', 'Sahtiyan', 'SQLServerDBA', '555 55 55'
GO

alter index IX_ColumnsStoreIndex on dbo.DenemeTbl rebuild
GO

 

9

Her işlemden önce disable, sonrasında rebuild ilk etapta kulağa hoş gelmese de ColumnStore index’in DWH sistemleri için bir yenilik olduğunu unutmamak gerekir. DWH sistemleri çok fazla data değişimi yaşamadığından hatta çoğu zaman günde 1 kez populate olduğundan dolayı populate’ten önce disable ve sonra rebuild etmek çok problem çıkaracak bir durum gibi gözükmemektedir.

Sonuç

ColumnStore Index, SQL Server 2011 Denali ile gelen, DWH sistemlerinde bulunan büyük tablolar için performans arttırıcı yeni bir index tipidir. Kayıtları satır bazında değil kolon bazında tutuyor olması en büyük özelliğidir. Bu şekilde sadece istenen kolon ile ilgili page’lerin okunması yeterlidir. Ayrıca aynı kolonların verisinin aynı olma ihtimalinden dolayı ColumnStore index’lerde sıkıştırma oranı çok daha fazladır. Bu da index’in daha az page’ten oluşmasını dolayısıyla daha performanslı çalışmasını sağlamaktadır.

Özellikle ETL süreçlerini düşündüğümüzde, verinin extract edilmesi esnasında okunan verilerin ColumnStore indexlerden karşılanması verilerin çok fazla miktarlarda olduğunu göz önünde bulundurduğumuz senaryolarda veritabanı sunucularında bulanan memory baskısını ciddi oranda azaltacaktır , bu durum sistemimiz üzerinde olumlu bir performans etkisi yaratacaktı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


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


12.04.2011 tarihinde gerçekleştirmiş olduğum SQL Server’da Index Kavramı - Performance Tuning ve Query Optimization başlıklı webcast’imin videosu aşağıdadır.

Webcast’te kullandığım sunum dosyası ve scriptleri şuradan ulaşabilirsiniz.

İyi seyirler

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


SQL Server’ın yeni versiyonu 2011 – Code Named “Denali” ‘nin CTP3’ü çıktı. Aşağıdaki adresten download edebilirsiniz.

http://www.microsoft.com/sqlserver/en/us/future-editions.aspx

CTP1 üzerinde aşağıdaki makaleleri yazma fırsatı bulmuştum.

SQL Server 2011 Denali–Distributed Replay Utility

SQL Server 2011 Denali - SQL Server Developer Tool (SSDT) Code-Named “Juneau”

SQL Server 2011 Denali–Column Based Query Accelarator (Code Named Apollo)

SQL Server 2011 Denali–HADR (High Availability and Disaster Recovery)

SQL Server 2011 “Denali” – Contained Database User

SQL Server 2011 “Denali” – Contained Database

SQL Server 2011 “Denali” – Code Snippets

SQL Server 2011 “Denali” - Sequence Objects

SQL Server 2011 “Denali” - Ad-Hoc Query Paging–Sayfalama

SQL Server 2011 “Denali” – EXEC Komutunda WITH RESULT SETS Seçeneği

SQL Server 2011 “Denali” – SQL Server Configuration Manager – Startup Parameters

SQL Server 11 “Denali” – Kendi Server Role’lerimizi Oluşturalım

SQL Server 2011 “Denali” Kurulumu (Installation)

 

CTP3 ile beraber daha derin olarak denemek istediğim 2011 Denali ile gelen yeni gelen özellikler Distributed AlwaysOn, Replay Utility ve Column Based Query Accelarator.

En kısa zamanda incelemeler yapıp makaleler yazıyor olacağım.

 

İ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


02.05.2011 tarihinde gerçekleştirmiş olduğum Microsoft SQL Azure’a Genel Bakış, SQL Azure Veritabanına İlk Bağlantı başlıklı webcast’imin videosu aşağıdadır.

[more]

İyi seyirler

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


SQL Server 2008 R2, sunucu ve veritabanı seviyesinde daha güvenlikli bir ortam oluşturabilmek için bütün gerekli araçları sağlamaktadır. Görevler ayrılığı ilkesi kapsamında, SQL Server sunucusu üzerinde yetkili olan kişilerin minimum yetkiler ile ayarlanması, görevlerini yapabilecek kadar yetki ile donatılması yeterlidir.

Örneğin SQL Server DBA’lerin bile sysAdmin server role’un de olması pek güvenli bir ortam sağlamamaktadır. sysAdmin server role’u sunucu üzerinde yapılabilecek bütün işlemleri yapabildiği için çok zorda kalınmadıkça bu gruba kullanıcı dahil edilmemelidir.

SQL Server’da Görevler Ayrılığı'nın detaylarının anlatıldığı aşağıdaki whitepaper’ın ilginizi çekeceğini umuyorum.

SQL Server Seperation of Duties

 

İ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