Mikro ERP SQL Server Performans Optimizasyonu: Yavaşlığın 7 Kaynağı ve Çözüm Rehberi
Mikro ERP veritabanınız yavaş mı çalışıyor? STOK_HAREKETLERI ve CARI_HESAP_HAREKETLERI tablolarında index stratejisi, TempDB optimizasyonu, Wait Stats analizi, Execution Plan okuma ve otomatik bakım planı ile SQL Server performansını 5-10x artırın.
Mikro ERP’de en sık duyduğumuz şikayet: “Program çok yavaş.” Fatura kaydı 10 saniye sürüyor, stok raporu 2 dakikada açılıyor, cari ekstre sorgusu timeout veriyor.
Sorun genellikle Mikro yazılımının kendisinde değil, SQL Server yapılandırmasında ve veritabanı bakımsızlığında. Bu rehber, Mikro ERP veritabanınızdaki yavaşlığın gerçek kaynaklarını tespit etmenizi ve adım adım çözmenizi sağlayacak.
Başlamadan Önce: Teşhis → Tedavi
Performans optimizasyonunda en büyük hata körlemesine index eklemek veya donanım yükseltmektir. Doğru yaklaşım:
1. Ölç → Yavaşlığın kaynağını tespit et (Wait Stats)
2. Analiz → Sorunlu sorguları bul (Execution Plan)
3. Uygula → Hedefe yönelik çözüm (Index, TempDB, Ayar)
4. Doğrula → İyileşmeyi ölç, yeni darboğaz var mı kontrol et
⚠️ Uyarı: Bu rehberdeki tüm SQL komutlarını önce test ortamında deneyin. Canlı veritabanında değişiklik yapmadan önce mutlaka tam yedek alın.
1. SQL Server Sürümü: Express Tuzağı
Mikro ERP kurulumlarının büyük çoğunluğu SQL Server Express ile gelir. Express sürümünün kritik sınırlamaları:
| Özellik | Express | Standard | Developer |
|---|---|---|---|
| Maksimum RAM | 1,4 GB | 128 GB | Sınırsız |
| Maksimum CPU | 4 çekirdek | 24 çekirdek | Sınırsız |
| Veritabanı Boyutu | 10 GB | 524 PB | Sınırsız |
| Paralel Sorgu | Yok | Var | Var |
| Fiyat | Ücretsiz | Lisanslı | Ücretsiz (üretim dışı) |
Veritabanı Boyutunuzu Kontrol Edin
-- Mikro ERP veritabanı boyutunu kontrol et
SELECT
DB_NAME(database_id) AS Veritabani,
type_desc AS Dosya_Tipi,
name AS Dosya_Adi,
size * 8 / 1024 AS Boyut_MB,
CAST(size * 8.0 / 1024 / 1024 AS DECIMAL(10,2)) AS Boyut_GB
FROM sys.master_files
WHERE DB_NAME(database_id) NOT IN ('master', 'model', 'msdb', 'tempdb')
ORDER BY size DESC;
Eğer veritabanınız 7-8 GB’ı aşıyorsa, Express sürümünde ciddi yavaşlık yaşamaya başlarsınız. 10 GB sınırına yaklaştığınızda ise veritabanı büyüyemez ve hata verir.
Ne Yapmalı?
- Veritabanı < 5 GB: Express yeterli, diğer optimizasyonlara geçin
- Veritabanı 5-10 GB: Acil Standard’a geçiş planlayın
- Test/Geliştirme: Developer Edition tamamen ücretsiz ve sınırsız (üretimde kullanılamaz)
2. Kritik Tabloları Tanıyın: Yavaşlık Nerede?
Mikro ERP’de tüm tablolar eşit yoğunlukta değildir. Yavaşlığın %80’i genellikle şu 4 tabloda yaşanır:
| Tablo | Prefix | Ortalama Kayıt | Tipik Sorun |
|---|---|---|---|
CARI_HESAP_HAREKETLERI | cha_ | 500K – 5M | Ekstre, yaşlandırma raporları |
STOK_HAREKETLERI | sth_ | 500K – 10M | Stok bakiye, maliyet raporları |
SIPARISLER | sip_ | 100K – 1M | Açık sipariş, teslimat raporları |
STOKLAR | sto_ | 10K – 100K | Fiyat listesi, stok arama |
Tablo Boyutlarınızı Ölçün
-- En buyuk 15 tabloyu listele (satir sayisi + boyut)
SELECT TOP 15
s.name + '.' + t.name AS Tablo,
p.rows AS Satir_Sayisi,
CAST(SUM(a.total_pages) * 8.0 / 1024 AS DECIMAL(10,2)) AS Boyut_MB,
CAST(SUM(a.used_pages) * 8.0 / 1024 AS DECIMAL(10,2)) AS Kullanilan_MB
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.indexes i ON t.object_id = i.object_id
INNER JOIN sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id
INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
WHERE t.is_ms_shipped = 0
GROUP BY s.name, t.name, p.rows
ORDER BY SUM(a.total_pages) DESC;
Sonuçta CARI_HESAP_HAREKETLERI ve STOK_HAREKETLERI tablolarının boyutuna dikkat edin. 1 GB’ı aşan tablolarda index stratejisi kritik hale gelir.
3. Wait Stats ile Yavaşlığın Kaynağını Bulun
SQL Server neden yavaş? Cevabı Wait Statistics verir. Her sorgu çalıştığında SQL Server bir kaynağı bekler — disk, bellek, kilit veya CPU. Wait Stats bu bekleme sürelerini kaydeder.
Mevcut Wait Stats’ı Sorgulayın
-- En cok beklemeye neden olan ilk 10 wait type
SELECT TOP 10
wait_type AS Bekleme_Tipi,
wait_time_ms / 1000 AS Toplam_Bekleme_Saniye,
signal_wait_time_ms / 1000 AS CPU_Bekleme_Saniye,
(wait_time_ms - signal_wait_time_ms) / 1000 AS Kaynak_Bekleme_Saniye,
waiting_tasks_count AS Bekleme_Sayisi
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN (
-- Arka plan ve bos bekleme tiplerini filtrele
'SLEEP_TASK', 'BROKER_TO_FLUSH', 'SQLTRACE_BUFFER_FLUSH',
'CLR_AUTO_EVENT', 'CLR_MANUAL_EVENT', 'LAZYWRITER_SLEEP',
'CHECKPOINT_QUEUE', 'WAITFOR', 'XE_TIMER_EVENT',
'REQUEST_FOR_DEADLOCK_SEARCH', 'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
'DIRTY_PAGE_POLL', 'XE_DISPATCHER_WAIT', 'BROKER_EVENTHANDLER',
'FT_IFTS_SCHEDULER_IDLE_WAIT', 'LOGMGR_QUEUE',
'ONDEMAND_TASK_QUEUE', 'SP_SERVER_DIAGNOSTICS_SLEEP',
'BROKER_RECEIVE_WAITFOR', 'PREEMPTIVE_OS_AUTHENTICATIONOPS'
)
AND wait_time_ms > 0
ORDER BY wait_time_ms DESC;
Sonuçları Nasıl Yorumlayacaksınız?
| Wait Type | Anlam | Çözüm |
|---|---|---|
PAGEIOLATCH_SH / EX | Veriler diskten okunuyor, bellekte bulunamıyor | 🔴 RAM yetersiz veya index eksik — en yaygın Mikro ERP sorunu |
CXPACKET | Paralel sorgu thread’leri birbirini bekliyor | Index eksik veya istatistikler güncel değil |
LCK_M_S / LCK_M_X | Kilitlenme — bir işlem diğerini bekliyor | Fatura kaydı sırasında rapor çekilmesi, uzun transaction’lar |
SOS_SCHEDULER_YIELD | CPU yetersiz, sorgular sıra bekliyor | CPU dar boğaz veya çok karmaşık sorgular |
WRITELOG | Transaction log yazma beklemesi | Log dosyası yavaş diskte |
Mikro ERP’de en sık görülen: PAGEIOLATCH — veriler bellekte tutulacak kadar RAM yok, her sorguda diskten okunuyor. Bu durumda index eklemek veya RAM artırmak en etkili çözümdür.
4. Eksik Index’leri Tespit Edin ve Akıllıca Ekleyin
SQL Server, çalıştırdığı her sorgunun “keşke şu index olsaydı daha hızlı olurdu” dediği yerleri kaydeder. Bu altın bilgiyi kullanarak doğru index’leri bulabilirsiniz.
Eksik Index Önerileri
-- SQL Server'in onerdigi eksik index'ler (en etkili ilk 15)
SELECT TOP 15
OBJECT_NAME(d.object_id) AS Tablo,
d.equality_columns AS Esitlik_Kolonlari,
d.inequality_columns AS Aralik_Kolonlari,
d.included_columns AS Dahil_Kolonlar,
CAST(s.avg_user_impact AS INT) AS Tahmini_Etki_Yuzde,
s.user_seeks AS Kullanilacak_Sayisi,
CAST(s.avg_total_user_cost AS DECIMAL(10,2)) AS Ortalama_Maliyet
FROM sys.dm_db_missing_index_details d
INNER JOIN sys.dm_db_missing_index_groups g ON d.index_handle = g.index_handle
INNER JOIN sys.dm_db_missing_index_group_stats s ON g.index_group_handle = s.group_handle
WHERE d.database_id = DB_ID()
ORDER BY s.avg_user_impact * s.user_seeks DESC;
Mikro ERP İçin Önerilen Temel Index’ler
Aşağıdaki index’ler çoğu Mikro ERP kurulumunda fark yaratır. Bunlar hareket tablolarındaki en sık kullanılan filtreleme ve sıralama alanlarını kapsar:
-- =============================================
-- CARI_HESAP_HAREKETLERI: Tarih + Kod Filtresi
-- Fayda: Cari ekstre, yaslandirma, tahsilat raporlari
-- =============================================
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE name = 'IX_CHA_Kod_Tarih'
AND object_id = OBJECT_ID('dbo.CARI_HESAP_HAREKETLERI')
)
CREATE NONCLUSTERED INDEX IX_CHA_Kod_Tarih
ON dbo.CARI_HESAP_HAREKETLERI (cha_kod, cha_tarihi)
INCLUDE (cha_tip, cha_meblag, cha_evrak_tip, cha_cinsi, cha_iptal)
WITH (ONLINE = ON, FILLFACTOR = 90);
-- ONLINE=ON: Index olusturulurken tablo kilitlenmez
-- FILLFACTOR=90: Sayfalarda %10 bos alan birak (INSERT performansi icin)
-- =============================================
-- STOK_HAREKETLERI: Stok Kodu + Tarih Filtresi
-- Fayda: Stok bakiye, maliyet, hareket raporlari
-- =============================================
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE name = 'IX_STH_StokKod_Tarih'
AND object_id = OBJECT_ID('dbo.STOK_HAREKETLERI')
)
CREATE NONCLUSTERED INDEX IX_STH_StokKod_Tarih
ON dbo.STOK_HAREKETLERI (sth_stok_kod, sth_tarih)
INCLUDE (sth_tip, sth_miktar, sth_tutar, sth_cins, sth_giris_depo_no, sth_cikis_depo_no)
WITH (ONLINE = ON, FILLFACTOR = 90);
-- =============================================
-- STOK_HAREKETLERI: Cari Kodu Filtresi
-- Fayda: Cariye gore satis/alis raporlari
-- =============================================
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE name = 'IX_STH_CariKod_Tarih'
AND object_id = OBJECT_ID('dbo.STOK_HAREKETLERI')
)
CREATE NONCLUSTERED INDEX IX_STH_CariKod_Tarih
ON dbo.STOK_HAREKETLERI (sth_cari_kodu, sth_tarih)
INCLUDE (sth_stok_kod, sth_tip, sth_miktar, sth_tutar)
WITH (ONLINE = ON, FILLFACTOR = 90);
-- =============================================
-- SIPARISLER: Musteri Kodu + Tarih Filtresi
-- Fayda: Acik siparis, teslimat raporlari
-- =============================================
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE name = 'IX_SIP_MusteriKod_Tarih'
AND object_id = OBJECT_ID('dbo.SIPARISLER')
)
CREATE NONCLUSTERED INDEX IX_SIP_MusteriKod_Tarih
ON dbo.SIPARISLER (sip_musteri_kod, sip_tarih)
INCLUDE (sip_stok_kod, sip_miktar, sip_teslim_miktar, sip_tip, sip_cins)
WITH (ONLINE = ON, FILLFACTOR = 90);
⚡ Önemli: Index Ekleme Kuralları
- Körlemesine eklemeyin. Önce eksik index sorgusunu çalıştırın, SQL Server’ın önerisini görün
- INCLUDE kolonlarını ayarlayın. Raporda gösterdiğiniz alanları INCLUDE’a ekleyin — Key Lookup’ı önler
- Test edin. Canlı ortamda index oluşturmadan önce test ortamında deneyin
- Gece çalıştırın. Büyük tablolarda index oluşturma uzun sürebilir (ONLINE=ON kullanın)
- Fazla index = yavaş yazma. Her
INSERTveUPDATEişleminde tüm index’ler güncellenir. Tablo başına 5-7 index idealdir
5. TempDB Optimizasyonu
TempDB, SQL Server’ın geçici işlem alanıdır. Sıralama, gruplama, JOIN, cursor ve geçici tablolar burayı kullanır. Mikro ERP’deki raporların çoğu karmaşık JOIN ve GROUP BY işlemleri yaptığı için TempDB performansı kritiktir.
TempDB Durumunu Kontrol Edin
-- TempDB dosya durumu ve boyutlari
SELECT
name AS Dosya_Adi,
physical_name AS Dosya_Yolu,
size * 8 / 1024 AS Boyut_MB,
growth AS Buyume_Ayari,
CASE is_percent_growth
WHEN 1 THEN CAST(growth AS VARCHAR) + '%'
ELSE CAST(growth * 8 / 1024 AS VARCHAR) + ' MB'
END AS Buyume_Miktari
FROM tempdb.sys.database_files;
TempDB Optimizasyon Kuralları
Kural 1: Dosya Sayısı = CPU Çekirdek Sayısı (max 8)
-- Sunucunuzdaki CPU cekirdek sayisini kontrol edin
SELECT cpu_count AS Toplam_CPU, hyperthread_ratio AS HT_Orani
FROM sys.dm_os_sys_info;
Örneğin 4 çekirdekli bir sunucuda TempDB’de 4 data file olmalıdır. Tüm dosyalar aynı boyutta olmalı:
-- TempDB'ye yeni dosya ekleme (ornek: 4 cekirdek icin 4 dosya, her biri 512 MB)
-- NOT: Bu komutu calistirmadan once mevcut dosya sayinizi kontrol edin
ALTER DATABASE tempdb
ADD FILE (
NAME = 'tempdev2',
FILENAME = 'D:\SQLData\tempdev2.ndf', -- Hizli bir SSD yolu verin
SIZE = 512MB,
FILEGROWTH = 256MB
);
-- Diger dosyalar icin tekrarlayin (tempdev3, tempdev4)
Kural 2: TempDB’yi Ayrı Diske Taşıyın
TempDB kesinlikle ana veritabanı ile aynı diskte olmamalıdır. Mümkünse SSD/NVMe üzerine taşıyın.
Kural 3: Otomatik Küçültme (Shrink) Kullanmayın
tempdb için asla DBCC SHRINKFILE çalıştırmayın. SQL Server yeniden başladığında TempDB zaten başlangıç boyutuna döner.
6. En Yavaş Sorguları Bulun
Hangi sorgular en çok kaynak tüketiyor? SQL Server bunu sizin için kaydeder:
Top 10 Kaynak Tüketen Sorgu
-- En cok CPU + IO tuketen 10 sorgu
SELECT TOP 10
SUBSTRING(qt.text, (qs.statement_start_offset / 2) + 1,
(CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset) / 2 + 1) AS Sorgu_Metni,
qs.execution_count AS Calisma_Sayisi,
qs.total_elapsed_time / 1000 AS Toplam_Sure_ms,
qs.total_elapsed_time / qs.execution_count / 1000 AS Ortalama_Sure_ms,
qs.total_logical_reads AS Toplam_Okuma,
qs.total_logical_reads / qs.execution_count AS Ortalama_Okuma,
qs.total_worker_time / 1000 AS Toplam_CPU_ms
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
WHERE qt.dbid = DB_ID()
ORDER BY qs.total_elapsed_time DESC;
Execution Plan Okuma Rehberi
Yavaş bir sorguyu bulduktan sonra çalıştırma planını görüntüleyin:
-- Sorgunun execution plan'ini goruntule
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
-- Yavaş sorgunuzu buraya yapistirin
-- Ornek: Cari ekstre raporu
SELECT cha_kod, cha_tarihi, cha_tip, cha_meblag
FROM CARI_HESAP_HAREKETLERI WITH (NOLOCK)
WHERE cha_kod = '120.001'
AND cha_tarihi >= '2026-01-01'
AND cha_iptal = 0
ORDER BY cha_tarihi;
SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
SSMS’de çalıştırma planını görsel olarak görmek için: Ctrl + M (Include Actual Execution Plan) tuşlayın, sorguyu çalıştırın, alt paneldeki “Execution Plan” sekmesine bakın.
Execution Plan’da Neye Bakmalı?
| Operasyon | İyi mi? | Anlam |
|---|---|---|
| Index Seek | ✅ İyi | Index üzerinden doğrudan erişim — hızlı |
| Index Scan | ⚠️ Kötü olabilir | Tüm index taranıyor — çok kayıt okuyor |
| Table Scan | 🔴 Kötü | Tüm tablo satır satır taranıyor — index yok |
| Key Lookup | ⚠️ Kötü olabilir | Index buldu ama ek kolonlar için tabloya geri dönüyor — INCLUDE eksik |
| Sort | ⚠️ Dikkat | Bellek yetmezse TempDB’ye taşar — yavaşlatır |
| Hash Match | ⚠️ Dikkat | Büyük tablolarda JOIN — bellek yoğun |
Hedef: Table Scan → Index Seek dönüşümü. Bir tablo taramasını index aramasına çevirmek sorguyu 10-100x hızlandırabilir.
7. Otomatik Bakım Planı Oluşturun
Veritabanı bakımı yapılmazsa zamanla yavaşlar. Index’ler parçalanır, istatistikler eskir, log dosyası şişer. Aşağıdaki bakım işlemlerini haftalık çalıştırın:
Index Bakımı (Reorganize / Rebuild)
-- Index parcalanma oranlarini kontrol et
SELECT
OBJECT_NAME(ips.object_id) AS Tablo,
i.name AS Index_Adi,
ips.avg_fragmentation_in_percent AS Parcalanma_Yuzde,
ips.page_count AS Sayfa_Sayisi,
CASE
WHEN ips.avg_fragmentation_in_percent < 10 THEN 'Islem gereksiz'
WHEN ips.avg_fragmentation_in_percent < 30 THEN 'REORGANIZE onerisi'
ELSE 'REBUILD onerisi'
END AS Oneri
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') ips
INNER JOIN sys.indexes i ON ips.object_id = i.object_id AND ips.index_id = i.index_id
WHERE ips.avg_fragmentation_in_percent > 5
AND ips.page_count > 1000 -- Kucuk tablolari atla
ORDER BY ips.avg_fragmentation_in_percent DESC;
Parçalanma Kuralları
| Parçalanma % | İşlem | Komut |
|---|---|---|
| < %10 | Bir şey yapma | — |
| %10 – %30 | Reorganize | ALTER INDEX [IndexAdi] ON [Tablo] REORGANIZE; |
| > %30 | Rebuild | ALTER INDEX [IndexAdi] ON [Tablo] REBUILD WITH (ONLINE = ON); |
Tüm Index’leri Otomatik Bakım (Script)
-- Tum tablolardaki parcalanmis index'leri otomatik bakim yap
DECLARE @TabloDB NVARCHAR(256), @IndexDB NVARCHAR(256), @SqlDB NVARCHAR(MAX);
DECLARE @Frag FLOAT;
DECLARE IndexBakim CURSOR FOR
SELECT
QUOTENAME(OBJECT_SCHEMA_NAME(ips.object_id)) + '.' + QUOTENAME(OBJECT_NAME(ips.object_id)),
QUOTENAME(i.name),
ips.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') ips
INNER JOIN sys.indexes i ON ips.object_id = i.object_id AND ips.index_id = i.index_id
WHERE ips.avg_fragmentation_in_percent > 10
AND ips.page_count > 1000
AND i.name IS NOT NULL;
OPEN IndexBakim;
FETCH NEXT FROM IndexBakim INTO @TabloDB, @IndexDB, @Frag;
WHILE @@FETCH_STATUS = 0
BEGIN
IF @Frag < 30
SET @SqlDB = N'ALTER INDEX ' + @IndexDB + N' ON ' + @TabloDB + N' REORGANIZE;';
ELSE
SET @SqlDB = N'ALTER INDEX ' + @IndexDB + N' ON ' + @TabloDB + N' REBUILD WITH (ONLINE = ON);';
PRINT @SqlDB;
EXEC sp_executesql @SqlDB;
FETCH NEXT FROM IndexBakim INTO @TabloDB, @IndexDB, @Frag;
END
CLOSE IndexBakim;
DEALLOCATE IndexBakim;
PRINT 'Index bakim tamamlandi.';
İstatistikleri Güncelle
-- Tum tablolarin istatistiklerini guncelle
-- Haftada 1 calistirin, tercihen gece
EXEC sp_updatestats;
-- Veya sadece kritik tablolar icin:
UPDATE STATISTICS dbo.CARI_HESAP_HAREKETLERI WITH FULLSCAN;
UPDATE STATISTICS dbo.STOK_HAREKETLERI WITH FULLSCAN;
UPDATE STATISTICS dbo.SIPARISLER WITH FULLSCAN;
FULLSCAN tablonun %100’ünü okuyarak en doğru istatistiği üretir. Tablo çok büyükse SAMPLE 50 PERCENT kullanabilirsiniz.
Bonus: Mikro ERP’ye Özgü Hızlı Kazanımlar
WITH (NOLOCK) Kullanımı
Raporlama sorgularınızda WITH (NOLOCK) kullanmak kilit bekleme süresini ortadan kaldırır. Mikro ERP’nin kendi raporları zaten bu tekniği kullanır:
-- Raporlama icin: Kilitsiz okuma
SELECT cha_kod, SUM(cha_meblag) AS Toplam
FROM CARI_HESAP_HAREKETLERI WITH (NOLOCK)
WHERE cha_tarihi >= '2026-01-01'
AND cha_iptal = 0
GROUP BY cha_kod;
⚠️
WITH (NOLOCK)uncommitted (henüz onaylanmamış) verileri de okuyabilir. Rapor sorgularında kabul edilebilir ama veri güncelleyen sorgularda asla kullanmayın.
Kullanılmayan Index’leri Tespit Edin
Çok fazla index yazma performansını düşürür. Hiç kullanılmayan index’leri tespit edin:
-- Son SQL Server restart'indan bu yana hic kullanilmamis index'ler
SELECT
OBJECT_NAME(i.object_id) AS Tablo,
i.name AS Index_Adi,
i.type_desc AS Index_Tipi,
dm.user_seeks AS Seek_Sayisi,
dm.user_scans AS Scan_Sayisi,
dm.user_lookups AS Lookup_Sayisi,
dm.user_updates AS Guncelleme_Sayisi
FROM sys.indexes i
LEFT JOIN sys.dm_db_index_usage_stats dm ON i.object_id = dm.object_id
AND i.index_id = dm.index_id
AND dm.database_id = DB_ID()
WHERE OBJECTPROPERTY(i.object_id, 'IsUserTable') = 1
AND i.type_desc = 'NONCLUSTERED'
AND ISNULL(dm.user_seeks, 0) + ISNULL(dm.user_scans, 0) + ISNULL(dm.user_lookups, 0) = 0
AND dm.user_updates > 100 -- Sadece guncellenen ama hic okunmayan
ORDER BY dm.user_updates DESC;
SQL Server Bellek Ayarı
SQL Server varsayılan olarak sunucudaki tüm RAM’i almaya çalışır. Mikro ERP sunucusunda başka uygulamalar da çalışıyorsa (Mikro istemci, Windows servisleri) SQL Server’a maksimum bellek limiti verin:
-- SQL Server'a maksimum bellek siniri ver
-- Toplam RAM: 16 GB ise → SQL Server'a 12 GB ver, 4 GB isletim sistemine birak
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'max server memory (MB)', 12288; -- 12 GB = 12 * 1024
RECONFIGURE;
-- Ayari dogrula
EXEC sp_configure 'max server memory (MB)';
Genel kural: Toplam RAM’in %75-80’ini SQL Server’a verin. Kalan %20-25 işletim sistemi ve diğer servisler içindir.
Kontrol Listesi: Hemen Yapılacaklar
| # | İşlem | Komut/Adım | Öncelik |
|---|---|---|---|
| 1 | SQL Server sürümünü kontrol et | SELECT @@VERSION | 🔴 |
| 2 | Veritabanı boyutunu kontrol et | Yukarıdaki sorguyu çalıştır | 🔴 |
| 3 | Wait Stats’ı oku | Yukarıdaki sorguyu çalıştır | 🔴 |
| 4 | Eksik index önerilerini al | sys.dm_db_missing_index_details | 🔴 |
| 5 | Kritik tablolara index ekle | 4 temel index’i oluştur | 🟡 |
| 6 | TempDB dosya sayısını kontrol et | CPU çekirdeğe eşitle | 🟡 |
| 7 | Index parçalanmasını kontrol et | Bakım scriptini çalıştır | 🟡 |
| 8 | İstatistikleri güncelle | sp_updatestats | 🟡 |
| 9 | Max Memory ayarla | sp_configure | 🟢 |
| 10 | Haftalık bakım planı kur | SQL Agent Job oluştur | 🟢 |
Sonuç
Mikro ERP yavaşlığının çözümü çoğunlukla yazılım değişikliği değil, veritabanı yapılandırması ve düzenli bakımtır. Bu rehberdeki adımları sırayla uygularsanız:
- Wait Stats ile gerçek darboğazı tespit edersiniz (tahmin değil, veri)
- Index stratejisi ile
CARI_HESAP_HAREKETLERIveSTOK_HAREKETLERIsorgularını 5-10x hızlandırırsınız - TempDB optimizasyonu ile raporlardaki sıralama ve gruplama işlemlerini rahatlatırsınız
- Otomatik bakım ile performansın zamanla düşmesini engellersiniz
İlgili yazılar:
- Mikro ERP Cari Yaşlandırma Performans Optimizasyonu — fn_Aysm darboğazı ve hızlandırma teknikleri
- Mikro ERP CARI_HESAP_HAREKETLERI Tablo Rehberi — 185 alan, 137 evrak tipi
- Mikro ERP Tablo İlişkileri ve JOIN Rehberi — FK ilişkileri ve JOIN kalıpları
- Mikro ERP Depo Bazlı Stok Bakiye SQL — Stok raporlama sorguları