Forum
Arkadaşlar ;
Özel otomasyonumu sql 2000 den 2008R2 enterprise geçiş yaptık. sql 2000 silinip yerine 2008 R2 entprise sql kuruldu . 2003R2 64 bit sistem üzerine.
lakin program yavaşlıyor . Yazılımcı arkadaşlar indexler bozuluyor dedi nedeni ni araştırıyoruz.
birde sqlserv.exe çok az ram kullanımı göstermesine rağmen cihazda ram kullanımı totalde yüksek.
processes lerdeki kullanınal ramleri toplarsam yuksek çıkmıyor
Merhaba,
Aslında bir çok nedenden olabilecek bir konuya deyindiniz. Bu konu hakkında detaylı bilgilendirmeler yapabilirseniz size daha iyi yardımcı olabileceğimizi düşünüyorum.
İyi çalışmalar.
Merhaba,
Indexlerin bozulması tam olarak nasıl birşey ki ?
Indexleri bir maintenance ile rebuild edebilirsiniz. Böylece dedikleri sorun ortadan kalkacaktır. Harici olarak index kullanım durumları ile sistem DMV yada DMF ile kontrollerinizi de sağlayabilirsiniz.
Ram kullanımı konusuna gelecek olursak, SQL Server Performance Monitor ile counter ekleyip kontrolleri sağlayabilirsiniz.
sql stop ettiğimde ram kullanımı normal duruma geliyor. Demek ki bi şekilde işlemler arasında ram kullanan exe gizleniyor.
Merhaba Erol Bey,
Simdi sql server stop ettiginiz vakinde service kullanimda ve uygulama calismiyor oldugu icin ram kullanimi normal seviye gozukebilir, sql server start ettiginiz vakitte uygulama sql server process counter artis gosterecegi icin uygulama ram kullanimini artiracaktir ve bu artisi sql server kullaniyor diye dusunebilirsiniz.
Uygulama calisirken performance monitorden yada profiller uzerinden counter takibi ve query takibi yapabilir misiniz ?
Ayrica sql server max memory degerini set edildi mi ? sql server performance tuning islemi yapildi mi?
sql stop ettiğimde ram kullanımı normal duruma geliyor. Demek ki bi şekilde işlemler arasında ram kullanan exe gizleniyor.
Merhabalar,
Arkadaşların cevaplarına ek olarak SQL serverdaki Memory kulanımı yanlış anlaşılıyor.Biraz teknik bilgi ama işleyiş genel olarak aşağıdaki gibidir ve sql serverın bu denli memory'i işgal etmesi ki ozellikle enterprise ise sorun değildir.
SQL serverda memory management işlemi Lazywriter adlı process tarafından yapılır.Bu process belli zaman aralıkları ile calişip SQL server ve işletim sisteminin memory ye ihtiyacına gore SQL server tarafından kullanılan Memory i yi artırıp azaltır.Fakat Lazywriter sadece İşletim sistemi yeterli memory e sahip değilse sql server process nin kullandıgı memmory miktarını azaltır.Fakat bu azaltmayı yaparken memoryde bulunan execution plan gibi verileri disk e yazar.Fakat bu verilerin disk e yazılması bu verileri erşişimi yavaslatacagı için SQL server bu işlemleri yappıp Memory kullanımını gerekl,i değilse azaltmaz Yani sql server ın bu ram i kullanması çok anormal bir durum olmamakla beraber Memory üzerinde bi anormalik durumunu olcebileceiniz SQL Server Buffer Mgr adlı bir parametre var onunda değeri : Lazy Writes/Sec olarak hesaplanıyor.Bu değern cok yuksek olmaması gerekir ki bu değerin yuksek olması demek SQL server ınızın yeteri kadar memory si olmadıgına işarettir. Bu dğerde performance monitor aracılıgıyla erişebilirsiniz.
Kolay gelsin
Ram durumu anlaşıldı zaten sorunda çıkarmıyor gördüğüm kadarıyla.
ALTER INDEX ALL ON tabloadi REBUILD WITH (FILLFACTOR = 90)
komutu ile bakım yapıyoruz sorun düzeliyor . Ama kısa bir zaman içinde yeniden bozuluyor.
veri tabanı uyumluluğu tüm DB lerde sql 2000 ne göre ama sadece bir DB nin index i bozuluyor.
Bu sorununuz çözüldümü bilemiyorum ama çok basitçe aşağıdaki işlemleri uygulamanızı öneririm.Bu bilgileri %100 doğrudur ve işinize yarayacaktır diyemem. Kendi çalışma şeklinize ve projenize göre düzenlemeniz gerekecektir.
1-) INDEX bozuldu dediğiniz tabloya Insert işlemi nedir? (saniye, dakika, saat, gün olarak. bunun bir hesabını çıkartın)
2-) Insert edilen kayıtlar INDEX üzerine ciddi yük getiriyor mu? Zaten FILLFACTOR = 90 yaparak bir süre için düzeldiğini söylemişsiniz. Bu durumda FILLFACTOR = 70 yaparak izlemenizi öneririm. Ciddi anlamda rahatlatacaktır (diye düşünüyorum). Her gece INDEX DEFRAG yapılması sizi kurtaracaktır.
3-) Mümkünse DB lerini LIVE ve REPORT şeklinde ayırın. Bu durumda FILLFACTOR u çok daha alt seviyeye düşürebilir. LIVE da 50 - 60, Report da 90 - 100 gibi. Bu şekilde sorun yaşanacağını sanmıyorum. Tabiki her INDEX değerini bu kadar düşürmeyin. ardışık ID ler 90, 100 olabilirken, sürekli değişen alanlardan oluşan INDEX alanlarının değeri 50,60,70,80 olabilir.
4-) Bunlara ek olarak rapor alınırken sistem üzerine fazla yük binebilir. Raporda kullanılan alanlara göre INDEX yok ise sistem ciddi anlamda yavaşlacak buda INSERT, UPDATE gibi işlemlerin (DEAD LOCK) gecikmesine, yapılamamasına neden olacaktır.Yeni INDEX leri oluştururken bunların ne kadar hızlı dağılabileceğine dikkat edin. Tekrar ediyorum; çok fazla değişen değerlerden INDEX oluşturmak akıllıca değildir. (Mecbursanız FILLFCTOR olabildiğince düşük verin. 50,60,70 gibi)
Internet üzerinde araştırma ile bulduğum ve kendime göre düzenlemeye çalıştığım bazı komutlar aşağıdadır.
Umarım işinize yarar.
MISSING INDEX NASIL ÖĞRENİLİR?
select TOP 200 DB_NAME(id.database_id) as DatabaseName,
id.statement as TableName,
id.Equality_Columns,
id.Inequality_Columns,
id.Included_Columns,
gs.Last_user_seek,
gs.User_seeks,
gs.Last_user_scan,
gs.User_scans,
gs.avg_total_user_cost * gs.avg_user_impact * (gs.user_seeks + gs.user_scans) as ImprovementValue
from sys.dm_db_missing_index_group_stats gs
INNER JOIN sys.dm_db_missing_index_groups ig on gs.group_handle = ig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details id on id.index_handle = ig.index_handle
Where gs.avg_total_user_cost * gs.avg_user_impact * (gs.user_seeks + gs.user_scans) > 1000 --Improvement a göre göster
order by avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) desc
INDEX FRAGMANTATION NASIL ÖĞRENİLİR?
USE [DatabaseName]
GO
SELECT
/*ps.object_id,*/
i.name as IndexName,
OBJECT_NAME (ps.object_id) as ObjectName,
ps.index_id,
ps.avg_fragmentation_in_percent,
ps.page_count
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED') ps
INNER JOIN sys.indexes i ON i.object_id=ps.object_id and i.index_id=ps.index_id
WHERE avg_fragmentation_in_percent > 1 AND ps.index_id > 0
ORDER BY avg_fragmentation_in_percent
INDEX DEFRAG , REBUILD NASIL YAPILIR?
--------------------------------------------------------------------------
DECLARE
@OBJECT_ID INT,
@INDEX_NAME sysname,
@SCHEMA_NAME sysname,
@OBJECT_NAME sysname,
@AVG_FRAG float,
@command varchar(8000),
@RebuildCount int,
@ReOrganizeCount int,
@DBName varchar(100) = 'DatabaseName',
@RebuildRate int = 80,
@ReorganizeRate int = 10
CREATE TABLE #tempIM (
[ID] [INT] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[INDEX_NAME] sysname NULL,
[OBJECT_ID] INT NULL,
[SCHEMA_NAME] sysname NULL,
[OBJECT_NAME] sysname NULL,
[AVG_FRAG] float
)
SELECT @RebuildCount=0,@ReOrganizeCount=0
--Get Fragentation values
SELECT @command=
'Use ' + @DBName + ';
INSERT INTO #tempIM (OBJECT_ID, INDEX_NAME, SCHEMA_NAME, OBJECT_NAME, AVG_FRAG)
SELECT
ps.object_id,
i.name as IndexName,
OBJECT_SCHEMA_NAME(ps.object_id) as ObjectSchemaName,
OBJECT_NAME (ps.object_id) as ObjectName,
ps.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL , NULL, ''LIMITED'') ps
INNER JOIN sys.indexes i ON i.object_id=ps.object_id and i.index_id=ps.index_id
WHERE avg_fragmentation_in_percent > 0 AND ps.index_id > 0
and ps.database_id=DB_ID('''+@DBName+''')
ORDER BY avg_fragmentation_in_percent desc'
exec(@command)
DECLARE c CURSOR FAST_FORWARD FOR
SELECT OBJECT_ID,INDEX_NAME, SCHEMA_NAME, OBJECT_NAME, AVG_FRAG
FROM #tempIM
OPEN c
FETCH NEXT FROM c INTO @OBJECT_ID, @INDEX_NAME, @SCHEMA_NAME, @OBJECT_NAME, @AVG_FRAG
WHILE @@FETCH_STATUS = 0
BEGIN
--Reorganize or Rebuild
IF @AVG_FRAG > @RebuildRate
BEGIN
--Rebuild
SELECT @command = 'Use ' + @DBName + '; ALTER INDEX [' + @INDEX_NAME +'] ON ['
+ @SCHEMA_NAME + '].[' + @OBJECT_NAME + '] REBUILD WITH (ONLINE = ON )';
SET @RebuildCount = @RebuildCount+1
END ELSE IF @AVG_FRAG > @ReorganizeRate
BEGIN
--Reorganize
SELECT @command = 'Use ' + @DBName + '; ALTER INDEX [' + @INDEX_NAME +'] ON ['
+ @SCHEMA_NAME + '].[' + @OBJECT_NAME + '] REORGANIZE ';
SET @ReOrganizeCount = @ReOrganizeCount+1
END
ELSE BEGIN
--No Need
SELECT @command = ''
END
BEGIN TRY
EXEC (@command);
END TRY
BEGIN CATCH
END CATCH
FETCH NEXT FROM c INTO @OBJECT_ID, @INDEX_NAME, @SCHEMA_NAME, @OBJECT_NAME, @AVG_FRAG
END
CLOSE c
DEALLOCATE c
select * from #tempIM
DROP TABLE #tempIM
SELECT cast(@RebuildCount as varchar(5))+' index Rebuild,'+cast(@ReOrganizeCount as varchar(5))+' index Reorganize edilmistir.' as Result
--------------------------------------------------------------------------
Indexlerın tümünü sistemin offline olduğu bir zamanda drop edip tekrar create etmeyi denediniz mi ?