"Power BI Raporum Çok Yavaş" — En Sık Duyduğumuz Şikayet

Power BI forumlarının, Reddit r/PowerBI'ın ve Stack Overflow'un en popüler konusu: _"Raporum neden yavaş?"_ Bu sorunun cevabı genellikle üç yerde gizlidir: kötü veri modeli, optimize edilmemiş DAX veya fazla görsel.

Bu rehberde, forumlardan ve gerçek projelerimizden derlediğimiz en yaygın DAX performans sorunlarını ve kanıtlanmış çözümlerini paylaşıyoruz.

1. Performance Analyzer: İlk Adım

Herhangi bir optimizasyon yapmadan önce sorunun nerede olduğunu ölçün. Power BI Desktop'ta Performance Analyzer açın ve her görselin render süresini kontrol edin.

💡DAX Studio kullanarak sorguları doğrudan çalıştırıp server timing ile analiz edebilirsiniz. Her sorgunun Storage Engine (SE) ve Formula Engine (FE) süresini ayrı ayrı görürsünüz.

2. En Sık Yapılan DAX Hataları

Hata #1: CALCULATE İçinde Gereksiz Filtreler

Forumlarda en sık görülen pattern:

DAX
// ❌ YANLIŞ: İç içe CALCULATE
Kötü Measure = 
    CALCULATE(
        CALCULATE(
            SUM(Satış[Tutar]),
            Satış[Durum] = "Tamamlandı"
        ),
        Satış[Bölge] = "İstanbul"
    )

// ✅ DOĞRU: Tek CALCULATE, virgülle ayrılmış filtreler
İyi Measure = 
    CALCULATE(
        SUM(Satış[Tutar]),
        Satış[Durum] = "Tamamlandı",
        Satış[Bölge] = "İstanbul"
    )
⚠️İç içe CALCULATE kullanmak genellikle gereksizdir ve Formula Engine'i zorlar. Filtreleri tek CALCULATE içinde virgülle ayırın.

Hata #2: FILTER Yerine Boolean Filtre Kullanmamak

DAX
// ❌ YAVAŞ: Tablo tarama yapan FILTER
Yavaş = 
    CALCULATE(
        [Toplam Satış],
        FILTER(ALL(Satış), Satış[Tutar] > 1000)
    )

// ✅ HIZLI: Boolean filtre (Storage Engine'e pushdown)
Hızlı = 
    CALCULATE(
        [Toplam Satış],
        Satış[Tutar] > 1000
    )
💡FILTER(table, condition) tüm tabloyu tarar (satır-satır). Basit eşitlik/karşılaştırma filtreleri doğrudan CALCULATE'e yazılırsa Storage Engine seviyesinde çözülür — çok daha hızlı.

Hata #3: Değişkenlerden (VAR) Kaçınmak

VAR kullanmak, aynı hesaplamayı tekrar tekrar yapmaktan kurtarır. Motor, VAR'ı bir kez hesaplar ve sonucu cache'ler.

DAX
// ❌ YAVAŞ: Aynı hesaplama 3 kez yapılıyor
Kötü YoY = 
    DIVIDE(
        [Toplam Satış] - CALCULATE([Toplam Satış], SAMEPERIODLASTYEAR(Takvim[Tarih])),
        CALCULATE([Toplam Satış], SAMEPERIODLASTYEAR(Takvim[Tarih]))
    )

// ✅ HIZLI: VAR ile bir kez hesapla
İyi YoY = 
    VAR BuYil = [Toplam Satış]
    VAR GecenYil = CALCULATE([Toplam Satış], SAMEPERIODLASTYEAR(Takvim[Tarih]))
    RETURN
        DIVIDE(BuYil - GecenYil, GecenYil)

Hata #4: Calculated Column vs Measure Karışıklığı

Forumda en sık yanlış anlaşılan konu: Ne zaman Calculated Column, ne zaman Measure kullanılmalı?

| Durum | Doğru Seçim | Neden |

|---|---|---|

| Gruplamak istiyorum | Calculated Column | Satır bazlı değer gerekli |

| Toplam/ortalama istiyorum | Measure | Filter context'e göre değişmeli |

| IF ile kategori atamak | Calculated Column | Her satırda sabit |

| Yüzde hesaplama | Measure | Bağlama göre değişmeli |

DAX
// Calculated Column: Her satırda sabit bir kategori
Kârlılık Sınıfı = 
    IF(Satış[Kâr Marjı] >= 0.3, "Yüksek",
    IF(Satış[Kâr Marjı] >= 0.1, "Orta", "Düşük"))

// Measure: Bağlama göre değişen hesaplama
Kâr Yüzdesi = 
    DIVIDE(SUM(Satış[Kâr]), SUM(Satış[Gelir]))
⚠️Forum Hatası: "Measure yerine Calculated Column kullanıyorum ama sonuçlar yanlış" — Calculated Column filter context'ten etkilenmez. Toplamlar her zaman sabit kalır.

3. Veri Modeli Optimizasyonu

DAX hızlı olsa bile, kötü bir veri modeli her şeyi yavaşlatır.

Optimize Edilmiş Star Schema
FACTSatış TablosuDIMÜrünDIMMüşteriDIMZamanDIMMağaza

Altın Kurallar

  • Star Schema kullanın — her zaman
  • Gereksiz sütunları kaldırın — her kolon bellek tüketir
  • Yüksek kardinalite sütunlarını kaldırın — GUID, timestamp, uzun text
  • Ayrı takvim tablosu kullanın — CALENDARAUTO() yerine özel
DAX
// Özel takvim tablosu — her zaman daha iyi kontrol
Takvim = 
    VAR MinTarih = MIN(Satış[Tarih])
    VAR MaxTarih = MAX(Satış[Tarih])
    RETURN
    ADDCOLUMNS(
        CALENDAR(MinTarih, MaxTarih),
        "Yıl", YEAR([Date]),
        "Ay No", MONTH([Date]),
        "Ay Adı", FORMAT([Date], "MMMM", "tr-TR"),
        "Çeyrek", "Ç" & QUARTER([Date]),
        "YılAy", FORMAT([Date], "YYYYMM"),
        "Hafta Sonu", IF(WEEKDAY([Date], 2) > 5, "Evet", "Hayır")
    )

4. Import vs DirectQuery vs Dual

| Mod | Performans | Güncellik | Boyut Limiti |

|---|---|---|---|

| Import | ⭐⭐⭐⭐⭐ | Zamanlanmış yenileme | ~1 GB (Pro), ~10 GB (Premium) |

| DirectQuery | ⭐⭐ | Gerçek zamanlı | Sınırsız |

| Composite/Dual | ⭐⭐⭐⭐ | Karma | Esnek |

| DirectLake | ⭐⭐⭐⭐⭐ | Gerçek zamanlı | Fabric kapasitesine bağlı |

💡Fabric kullanıyorsanız DirectLake modunu tercih edin. Import performansını DirectQuery güncelliğiyle birleştirir.

5. DAX Studio ile İleri Seviye Analiz

DAX Studio, ücretsiz ve Power BI optimizasyonu için vazgeçilmez bir araçtır. Server Timing özelliği ile:

  • SE (Storage Engine): Verinin diskten/bellekten okunma süresi
  • FE (Formula Engine): DAX hesaplamaları süresi
  • SE/FE oranı: İdeal oran SE ağırlıklı olmalı
DAX
// DAX Studio'da çalıştırın ve Server Timing'i açın
EVALUATE
SUMMARIZECOLUMNS(
    Takvim[Yıl],
    Takvim[Ay Adı],
    "Toplam", [Toplam Satış],
    "YoY", [İyi YoY]
)
ORDER BY Takvim[Yıl], Takvim[Ay Adı]

6. Performans Kontrol Listesi

Rapor yavaşladığında sırayla kontrol edin:

  • ✅ Veri modeli Star Schema olmalı
  • ✅ Kullanılmayan sütunları Power Query'de kaldırın
  • ✅ Sayfa başına maksimum 8 görsel — daha fazlası performansı düşürür
  • FILTER(ALL(table)) yerine boolean filtre kullanın
  • ✅ Tekrarlanan hesaplamalarda VAR kullanın
  • ✅ 1 GB altı veriler için Import, üstü için Composite/DirectLake

Sonuç

Power BI performans sorunlarının %80'i kötü veri modeli ve optimize edilmemiş DAX'tan kaynaklanır. Star Schema kullanın, gereksiz sütunları kaldırın, CALCULATE içinde boolean filtreler tercih edin ve VAR ile tekrarlanan hesaplamalardan kaçının. DAX Studio ve Performance Analyzer ile ölçün, tahmin etmeyin.