MSSQL Server Statistics Son Güncelleme Tarihini Bulmak

Aşağıdaki komut ile istatistiklerin en son ne zaman güncellendiğini bulabiliriz.

SELECT OBJECT_NAME(object_id) AS [Tablo İsmi]
      ,[name] AS [İstatistik İsmi]
      ,STATS_DATE([object_id], [stats_id]) AS [İstatistik Güncelleme Zamanı]
         ,datediff(DAY,(STATS_DATE([object_id], [stats_id])),GETDATE()) AS [En Son Güncelleme Günü]
FROM sys.stats
where OBJECT_NAME(object_id)='Address'

Aşağıda dikkat ederseniz Primary key istatistik değeri yeni güncellendiği için değeri 0 görülmektedir.

Aşağıdaki komut İstatistik üzerinde değişim yüzdesi %20 geçen istatistikleri göstermektedir. Aynı zamanda istatistik güncelleme komutunu görmekteyiz. Kaç gün önceki ifadelerin görülmesini istemiyorsak ilgili bölüm düzeltilebilir.

SELECT  
    'UPDATE STATISTICS ' + QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' +  
    QUOTENAME(OBJECT_NAME(s.object_id)) + ' ' + QUOTENAME(s.name) AS UpdateCommand,  
    DB_NAME() AS DatabaseName,  
    SCHEMA_NAME(t.schema_id) AS SchemaName,  
    OBJECT_NAME(s.object_id) AS TableName,  
    i.name AS IndexName,  
    s.name AS StatsName,  
    sp.last_updated AS LastUpdated,  
    sp.rows AS TotalRows,  
    sp.modification_counter AS ModifiedRows,  
    CAST(100.0 * sp.modification_counter / NULLIF(sp.rows, 0) AS DECIMAL(10,2)) AS ModificationPercent  
FROM sys.stats AS s  
JOIN sys.tables AS t ON s.object_id = t.object_id  
LEFT JOIN sys.indexes AS i ON s.object_id = i.object_id AND s.name = i.name  
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp  
WHERE sp.last_updated < DATEADD(DAY, -2, GETDATE())  -- Son 2 gündür güncellenmeyenler  
AND (100.0 * sp.modification_counter / NULLIF(sp.rows, 0)) > 20  -- %20'den fazla değişmiş olanlar  
ORDER BY sp.last_updated ASC;

Yukarıdaki komutu instance altında bulunan tüm veritabanları için yapmak istersek aşağıdaki komut kullanılmaktadır. Yukarıdaki komutta süre sınırı kaldırıla bilir.

exec sp_MSforeachdb'
 use [?] 
SELECT    top 5
''?'' as database_name,
...................'

Daha sonra ilgili ifadelerin update statistics komutlarını ayrı bir çıktı olarak almak istersek aşağıdaki scriptle alabiliriz.

DECLARE @cmd NVARCHAR(500);

DECLARE stats_cursor CURSOR FOR  
SELECT 'UPDATE STATISTICS ' + QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' +  
       QUOTENAME(OBJECT_NAME(s.object_id)) + ' ' + QUOTENAME(s.name)  
FROM sys.stats AS s  
JOIN sys.tables AS t ON s.object_id = t.object_id  
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp  
WHERE sp.last_updated < DATEADD(DAY, -2, GETDATE())  -- Son 2 gündür güncellenmeyenler  
AND (100.0 * sp.modification_counter / NULLIF(sp.rows, 0)) > 20;  -- %20'den fazla değişmiş olanlar

OPEN stats_cursor;  
FETCH NEXT FROM stats_cursor INTO @cmd;  
WHILE @@FETCH_STATUS = 0  
BEGIN  
    PRINT @cmd;  -- Komutu ekrana yazdır (kontrol için)  
    EXEC sp_executesql @cmd;  -- Güncelleme komutunu çalıştır  
    FETCH NEXT FROM stats_cursor INTO @cmd;  
END  
CLOSE stats_cursor;  
DEALLOCATE stats_cursor;

Aşağıdaki sorgu istatistiğin son güncelleme bilgilerini aynı zamanda yüzde kaç oranından istatistiğin güncellendiğini görebiliriz. Veritbanı adı, tablo adı ve scheme adının yazılması gerekmektedir.

use DB_NAME
DECLARE @objectID INT = OBJECT_ID('Scheme_Name' + '.' + 'Table_Name');
SELECT 
       [rowmodcounter].[modPercent], 
       names.dbName,
       names.schemaName,
       names.tableName,
       names.statsName,
       [s].[auto_created], 
       [s].[no_recompute], 
       [sp].[last_updated],
       [sp].[rows],
       [sp].[rows_sampled],
       [sp].[steps],
       [sp].[unfiltered_rows],
       [sp].[modification_counter],
       sampleRate = (1.0*sp.rows_sampled/sp.rows)*100,
       'UPDATE STATISTICS ' + names.schemaName + '.' + names.tableName + '(' + names.statsName + ')'
FROM [sys].[stats] s
CROSS APPLY [sys].[dm_db_stats_properties]([s].[object_id],[s].[stats_id]) sp
INNER JOIN [sys].[tables] t
       ON [s].[object_id] = [t].[object_id] 
CROSS APPLY (
                           SELECT (1.0*[sp].[modification_counter]/NULLIF([sp].[rows],0))*100
                           ) AS rowmodcounter(modPercent)
CROSS APPLY (SELECT 
       dbName              = DB_NAME(),
       schemaName          = SCHEMA_NAME(t.schema_id),
       tableName           = t.[name], 
       statsName           = s.[name]
       ) AS names
WHERE 
       (t.[object_id] = @objectID  OR @objectID IS NULL) 
       --AND [t].[is_ms_shipped] =0
       AND OBJECTPROPERTY(s.[object_id],'IsMSShipped')=0 
       --AND [rowmodcounter].[modPercent] >@modPercentLimit
ORDER BY [rowmodcounter].[modPercent] DESC;

sampleRate bölümünde ilgili istatistiğin kaç satır üzerinden yüzdelik olarak örneklendiğini görebiliriz. ModPercent bölümünden değişen istatistik değerlerinin yüzdelik olarak ifadesi görülmektedir.

Yukarıdaki komut belirtilen değerdeki istatistik güncelleme komutlarını güncel bir şekilde karşımıza vermektedir. Başka bir makalede görüşmek dileğiyle..

“Lokmân, “Sevgili oğlum” (dedi), “Yaptığın iş bir hardal tanesi ağırlığında bile olsa, bir kayanın içinde saklansa veya göklerde yahut yerin dibinde bulunsa yine de Allah onu açığa çıkarır. Kuşkusuz Allah her şeyi bütün gizlilikleriyle bilir, O her şeyden haberdardır.”Lokman-16

Author: Yunus YÜCEL

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir