SQL Server Cache Plan

Bu yazımızda sql server’da arka planda kullanılan, kaynak yönetimini ve sorgularımızı doğrudan ilgilendiren “Cache Plan” hakkında bilgileri ele alacağız. SQL Server’da bir sorgu ilk kez çalıştırıldığında derlenir (compile) ve query için bir plan oluşturulur. Bu plan sayesiyle sorgu hangi adımları izleyeceğini plana göre gerçekleştirir. Ve bu plan SQL Server’da Plan Cache içerisinde depolanır. Görsel -1 Plan cache içerisinde depolanan planlar sayesinde query tekrar geldiğinde yeni bir plan oluşturmasına gerek kalmaz ve aynı planı kullanarak sonucu geri döndürür. Bu sorgu planının ön bellekte kalma süresi sorgunun ne kadar kullanıldığı ile alakalıdır. Daha sık kullanılan sorgular plan cache’te daha fazla kalır. Plan Cache içerisinde tutabileceğim maximum plan sayısı 160.036. SQL Plans, Object Plans, Bound Trees, Extended SPs her biri için bu rakam 40.009’dur. Yoğun ad hoc sorguları SQL Plan bucket sayımızı arttırabilir ve bu durum SOS_CACHESTORE spinlock contention yaşamamıza neden olabilir. Bu durumun üstesinden -T174 Trace flag ekleyerek sayıyı 4 katına çıkarabiliriz. […]

SQL Server Cache Plan

Bu yazımızda sql server’da arka planda kullanılan, kaynak yönetimini ve sorgularımızı doğrudan ilgilendiren “Cache Plan” hakkında bilgileri ele alacağız.

SQL Server’da bir sorgu ilk kez çalıştırıldığında derlenir (compile) ve query için bir plan oluşturulur. Bu plan sayesiyle sorgu hangi adımları izleyeceğini plana göre gerçekleştirir. Ve bu plan SQL Server’da Plan Cache içerisinde depolanır.

Görsel -1

Plan cache içerisinde depolanan planlar sayesinde query tekrar geldiğinde yeni bir plan oluşturmasına gerek kalmaz ve aynı planı kullanarak sonucu geri döndürür.

Bu sorgu planının ön bellekte kalma süresi sorgunun ne kadar kullanıldığı ile alakalıdır. Daha sık kullanılan sorgular plan cache’te daha fazla kalır.

Plan Cache içerisinde tutabileceğim maximum plan sayısı 160.036. SQL Plans, Object Plans, Bound Trees, Extended SPs her biri için bu rakam 40.009’dur.

Yoğun ad hoc sorguları SQL Plan bucket sayımızı arttırabilir ve bu durum SOS_CACHESTORE spinlock contention yaşamamıza neden olabilir. Bu durumun üstesinden -T174 Trace flag ekleyerek sayıyı 4 katına çıkarabiliriz.

Size olarak ise;

0-4 GB memory’e sahip olduğunuz server üzerinde, maksimum %75’e ulaşabilirsiniz.

4-64 GB memory’e sahip olduğunuz server üzerinde, maksimum +%10’a ulaşabilirsiniz.

64 GB üzerinde memory’e sahip olduğunuz server üzerinde, maksimum +%25’e ulaşabilirsiniz.

Görsel – 2

 

Cache size değerini kontrol etmek için bir başka değiştirebileceğimiz değer ise sp_configure içerisinde “Optimize for ad hoc workload” değeri default option değeri 0’dır. Bu değeri 1’e setlediğimizde plan cache adhoc query’ler için plan cache size değerini arttırmış olacağız. Aşağıdaki sorgu ile bu değerin açık olup olmadığını kontrol edebilirsiniz.

Görsel – 3

 

USE master

GO

SELECT  CASE value_in_use

WHEN 0 THEN 'Optimize for Ad Hoc Workloads is Turned Off'

WHEN 1 THEN 'Optimize for Ad Hoc Workloads is Turned On'

END AS [Optimize for Ad Hoc Workloads Current Status]

FROM    sys.configurations

WHERE   name = 'optimize for ad hoc workloads';

GO

Görsel – 4

Bu değeri açmak istediğinizde aşağıdaki sp_configure komutlarını kullanarak açabilirsiniz. Fakat bu değeri açmadan önce kullanılan plan size ve sayısını kontrol etmenizde fayda var. Aşağıdaki script yardımı ile plan cache limit değerlerini kontol edebilirsiniz.

 

SELECT objtype AS [CacheType],

COUNT_BIG(*) AS [Total Plans],

SUM(CAST(size_in_bytes AS DECIMAL(18, 2))) / 1024 / 1024 AS [Total MBs],

AVG(usecounts) AS [Avg Use Count],

SUM(CAST((CASE WHEN usecounts = 1 THEN size_in_bytes

ELSE 0

END) AS DECIMAL(18, 2))) / 1024 / 1024 AS [Total MBs – USE Count 1],

SUM(CASE WHEN usecounts = 1 THEN 1

ELSE 0

END) AS [Total Plans – USE Count 1]

FROM sys.dm_exec_cached_plans

GROUP BY objtype

ORDER BY [Total MBs – USE Count 1] DESC

GO

veya

-- Plan cache contents and memory use by object type

SELECT  objtype, COUNT_BIG(*) AS plan_count, SUM(CAST(size_in_bytes AS DECIMAL(12, 2)))/(1024*1024) AS size_mb,

AVG(usecounts) AS avg_use_counts, SUM(CASE WHEN usecounts = 1 THEN 1 ELSE 0 END) AS single_use_plans,

SUM(CAST((CASE WHEN usecounts = 1 THEN size_in_bytes

ELSE 0 END) AS DECIMAL(12, 2)))/(1024*1024) AS single_use_mb

FROM    sys.dm_exec_cached_plans

WHERE cacheobjtype = N'Compiled Plan'

GROUP BY objtype;

 

“Optimize for ad hoc workloads” değerini aşağıdaki komutlar yardımı ile aktif edebiliriz;

 

sp_configure 'show advanced options',1;

RECONFIGURE;

GO

 

sp_configure 'optimize for ad hoc workloads',1;

RECONFIGURE;

GO

 

sp_configure 'show advanced options',0;

RECONFIGURE;

 

GO

 

Plan Cache dar boğazı yaşadığımızda bazı durumlarda cache boşaltmak bize avantaj sağlayabilir. Aşağıdaki sorgu ile single -use plan cache’ten dolayı, memory’i temizleme ihtiyacımız olup olmadığını bize bilgisini verecektir.

 

DECLARE @MB decimal(19,3)

, @Count bigint

, @StrMB nvarchar(20)

 

SELECT @MB = sum(cast((CASE WHEN usecounts = 1 AND objtype IN ('Adhoc', 'Prepared') THEN size_in_bytes ELSE 0 END) as decimal(12,2)))/1024/1024

, @Count = sum(CASE WHEN usecounts = 1 AND objtype IN ('Adhoc', 'Prepared') THEN 1 ELSE 0 END)

, @StrMB = convert(nvarchar(20), @MB)

FROM sys.dm_exec_cached_plans

 

IF @MB > 10

BEGIN

DBCC FREESYSTEMCACHE('SQL Plans')

RAISERROR ('%s MB was allocated to single-use plan cache. Single-use plans have been cleared.', 10, 1, @StrMB)

END

ELSE

BEGIN

RAISERROR ('Only %s MB is allocated to single-use plan cache – no need to clear cache now.', 10, 1, @StrMB)

 

END

Go

Bu işlemi otomatik olarak cache planların temizlenme işlemi aşağıdaki sorgu kullanılabilir. Ama bunun sisteme yük getireceğini unutmamak gereklidir.

 

DECLARE @MB decimal(19,3)

, @Count bigint

, @StrMB nvarchar(20)

 

SELECT @MB = sum(cast((CASE WHEN usecounts = 1 THEN size_in_bytes ELSE 0 END) as decimal(12,2)))/1024/1024

, @Count = sum(CASE WHEN usecounts = 1 THEN 1 ELSE 0 END)

, @StrMB = convert(nvarchar(20), @MB)

FROM sys.dm_exec_cached_plans

 

IF @MB > 1000

DBCC FREEPROCCACHE

ELSE

RAISERROR ('Only %s MB is allocated to single-use plan cache – no need to clear cache now.', 10, 1, @StrMB)

Go

Bu işlemi otomatik hale getirmek isterseniz, aşağıdaki Script’ten faydalanabilirsiniz.

https://www.sqlskills.com/blogs/kimberly/wp-content/uploads/2010/4/sp_SQLskills_CheckPlanCache.sql

 

Yukarıdaki scriptler yardımı ile planları temizleyeceğizdir fakat planları temizlemek bize yoğun sistemlerde dar boğaz yaratabilmektedir. Bunun sebebi ise her gelen sorgunun tekrardan yeni plan oluşturması ve bununda sistemde memory kullanımını arttırması demektir. Bu durumun sonucu bize CPU bottleneck olarak yansıyacaktır. Tüm Bu işlemleri Instance, Database ve Session bazında kontrol edip temizleme işlemlerini gerçekleştirebiliriz.

 

Tüm Db’lerdeki planları temizlemek istediğimizde ;

DBCC Freeproccache()

Speficif bir tipteki(object plans, SQL Plans etc.) planları temizlemek istediğimizde;

DBCC FREESYSTEMCACHE('SQL Plans');

Tek bir DB’deki Planları temizlemek istediğimizde;

ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;

Spesifik bir plana ait planı temizlemek istediğimizde;

ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE(<plan_handle>);

 

Plan Cache içerisinde neler barındırır dediğimizde;

Object Plan’lar: Store Procedure’ler, Function’lar ve Trigger’lar.

SQL Plans’lar: Prepared Plan’lar, Adhoc Plan’lar.

Diğer : Bound tree’ler ve Extented Store procedure Reference’leri.

Granularity: Statement Başına (per-statement) execution planlar. Object değil.

Statement başına Planlar (Plans per Statement): single statment için eğer farklı execution context’lere sahip ise multiple plan oluşturulabilir. Veya bir paralel plan üretilmiş olabilir.

 

Cache plan ile ilişkili olan Dynamic Management Object’ler bize hangi sorgunun hangi plan ile kaç kez çalıştırıldığı bilgisini verecektir. Aşağıdaki scirpt bize bu konuda faydalı olacaktır.

 

SELECT cplan.usecounts, cplan.objtype, qtext.text, qplan.query_plan, qstats.execution_count

FROM sys.dm_exec_cached_plans AS cplan

CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS qtext

CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS qplan

Inner Join sys.dm_exec_query_stats AS qstats on cplan.plan_handle = qstats.plan_handle

ORDER BY cplan.usecounts DESC

Bu Dynamic Management Object’lerin kendi aralarındaki ilişkin yapısını Görsel – 5 üzerinde inceleyebilirsiniz.

Görsel – 5

 

Database özelinde ve hangi query’nin nasıl bir performans tüketimi yaptığı konusunda aşağıdaki script bize fayda sağlayacaktır.

 

SELECT CASE st.dbid WHEN 32767 THEN 'resourcedb'

WHEN NULL THEN 'NA' ELSE DB_NAME(st.dbid)END AS [database], OBJECT_NAME(st.objectid) AS object_name,

SUBSTRING( st.text, ( qs.statement_start_offset / 2 ) + 1,

(( CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text)

ELSE qs.statement_end_offset END - qs.statement_start_offset ) / 2 ) + 1) AS sql_statement,

qs.exec_count, qs.avg_logical_reads, qs.avg_CPU_ms, qs.avg_time_ms, qs.avg_logical_writes, qp.query_plan

FROM ( SELECT TOP ( 10 ) plan_handle, statement_start_offset, statement_end_offset,

execution_count AS exec_count,

total_worker_time / ( execution_count * 1000 ) AS avg_CPU_ms,

( total_elapsed_time / ( execution_count * 1000 )) AS avg_time_ms,

CASE WHEN total_logical_reads > 0 THEN ( total_logical_reads / execution_count )

ELSE 0 END AS avg_logical_reads,

CASE WHEN total_logical_writes > 0 THEN ( total_logical_writes / execution_count )

ELSE 0 END AS avg_logical_writes

FROM sys.dm_exec_query_stats

ORDER BY ( total_logical_reads / execution_count ) DESC ) AS qs

CROSS APPLY sys.dm_exec_sql_text(qs.plan_handle) st

CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp

ORDER BY qs.avg_logical_reads DESC

OPTION ( RECOMPILE );

 

 

AdHoc Query’de aynı sorguların farklı plan kullandığını örneklemek istersek aşağıdaki örnek bizim için güzel bir örnek olacaktır. Bu sayede bize aynı sorgunun farklı plan kullandığı ve bize single-use plan kullanımının nasıl olduğu ve cache size sorununa nasıl sebep olduğunu daha iyi anlayabiliriz.

 

SELECT HASHBYTES('MD5','SELECT * FROM Person.Person') UNION ALL

SELECT HASHBYTES('MD5','SELECT * FROM person.Person') UNION ALL

SELECT HASHBYTES('MD5','SELECT *   FROM Person.Person')

/*

0xF2D4F28DA93156A5BB487B019F1F0191

0x76F700BB3DC09FF482E1E4A77C7392E8

0xB1D875A858F4D410D9E866C40E523683

*/
Benzer Yazılar

SQL SERVER RESOURCE GOVERNOR

SQL Server 5 saat önce

Bu makalede Sql Server ’da kaynak kullanımımız için farklı seçenekler ve değerlendirme fırsatları sunan Resource Governor yakından kullanım örneklerini göreceğiz. Günümüzde sistemlerimizin verimli kaynak kullanımı ve buna yönelik olarak çalışmalar oldukça önemli bir durumdadır. Bu kapsamda Veri tabanı sistemlerimizin kurulu olduğu sunucu kaynaklarımızdan maksimum faydayı ve verimi almaya çalışmaktayız. Bu kapsamda SQL Server veri tabanlarımızda kaynak (CPU, bellek, disk ve I/O) kullanımını yönetmek ve optimize etmek için kullanılan güçlü bir araç olan Resource Governor bizlere 2008 ve sonraki sürümlerde sunmaktadır. Bu sayede kritik iş yüklerinizin ihtiyaç duyduğu kaynaklara erişmesini sağlayabilir ve performansınızı optimize ederek veri tabanlarına gelebilecek aşırı yükü önlemiş olabilirsiniz. Biraz çalışma prensibinden bahsedelim, Resource Governor veri tabanı nesne ve sorgularında bir öncelik atayarak çalışır. Bunu şu şekilde örneklendirebiliriz sunucuya gelen uygulama sorguları var bunu servis kullanıcısı ile, raporlama sorguları var bunu raporlama kullanıcısı ile ve ilgili uygulamanın loglarının sorgulamasını yapan log kullanıcısı bulunmaktadır bu yapıda en öncelikli sorgularımız […]

SQL Server Trace Flag(Startup Parameters) Nedir? Ne için kullanılır ? Yaygın olarak kullanılan Trace Flaglar Nelerdir?

SQL Server 5 gün önce

Bu makalede, SQL Server Trace Flag ne olduğunu, nasıl kullanıldığını ve bazı yaygın senaryolarda nasıl faydalı olabileceğini inceleyeceğiz. Trace Flag Nedir ? SQL Server’ın davranışını değiştiren ve çeşitli senaryolarda performansı artıran veya hata ayıklama sürecini kolaylaştıran özel ayarlar olarak tanımlanabilir. Kullanım amaçları genel anlamda kriz anında ihtiyaçlara göre Trace Flags’ler eklenip problemi çözmeye yönelik işlemler yapılabilir. SQL Server Trace Flag seçerken dikkatli olmak önemlidir. Yanlış bir Trace flag etkinleştirilmesi, beklenmedik davranış değişikliklerine veya performans sorunlarına neden olabilir. Bu nedenle, her Trace Flag etkilerini ve kullanım senaryolarını bilmek önemlidir. Trace Flag etkinleştirildikten sonra sistem üzerindeki etkilerini izlemek ve değerlendirmek de önemlidir. Trace Flag nasıl aktif edebiliriz. Bağzı Trace Flag’ ler Service Restart edildikten sonra devreye girecektir. Aktif etmek için; SQL Server Configuration Manager/ SQL Server Services/ SQL Server (InstanceName)   Instance’a sağ tıklayıp Properties diyoruz ve Startup Parameters kısmına geliyoruz burada 3 tane System tarafından Default olarak gelen Trace Flag’ler bulunmaktadır. […]

SQL Server AlwaysON “Not Synchronizing / Suspect”

SQL Server 1 hafta önce

“Not Synchronizing / Suspect” SQL Serer AlwaysOn mimarisinde bulunan sunucuların veri tabanlarında bu sorunun meydana gelmesinde birçok neden vardır. Bunlar; Ağ Sorunları: AlwaysOn mimarisinde, ana sunucu ve ikincil sunucular arasında veri senkronizasyonu için gerekli olan ağ bağlantısı sorunları. Disk Sorunları: Veri tabanı dosyalarının tutulduğu disklerde disk doluluğu, disk arızası gibi disk sorunlarının meydana gelebilir. Log Dosyası Sorunları: Veri tabanlarının log dosyalarının bozulması veya dolması durumu. Bekleyen İşlemler: Veri tabanında bekleyen bir işlem (örneğin, büyük bir sorgu veya bir yedekleme işlemi) diğer işlemleri engellemesi durumunda. Veri tabanı Bozulması: Veri tabanı dosyalarında veya yapılarında bozulma meydana gelmesi. Bakım Yetersizliği: Düzenli yedekleme, veri tabanı kurtarma işlemleri vb. gibi veri tabanı yönetimi için gerekli düzenli bakımların yapılmaması. Bu gibi durumlarda, genellikle SQL Server hata günlüklerine bakarak daha spesifik bir sorun tespit edilebilir ve ardından uygun çözüm yolları belirlenebilir. Biz bu makalede disk sorunu ile karşılaşacağımız için disk sorununun tespiti ve çözümü üzerine gideceğiz. Karşılaşabileceğimiz […]

0 Yorum

Yorum Yaz

Rastgele