VertiPaq nasıl sıkıştırır?
- Sütun tabanlı: Her sütun ayrı saklanır. Rapor yalnızca kullandığı sütunları okur.
- Sözlük kodlaması: Metin değerleri bir sözlüğe yazılır, sütunda yalnızca tam sayı kodları tutulur. “İstanbul” milyon kez geçse de bir kez saklanır.
- Tekrar uzunluğu kodlaması (RLE): Aynı değerin art arda tekrarları “değer × adet” olarak saklanır.
Sonuç: Bir sütunun boyutunu en çok kardinalitesi (farklı değer sayısı) belirler. Satır sayısı ikinci sırada gelir.
Modeli küçültmek
- Kullanılmayan sütunları Power Query'de kaldır. Özellikle benzersiz kimlikler, açıklama metinleri, GUID'ler pahalıdır.
- Tarih-saat sütununu tarih ve saat olarak ikiye böl; saniyeyi gerekmedikçe tutma.
- Ondalık hassasiyeti azalt (Sabit ondalık sayı), metin yerine tam sayı anahtar kullan.
- Otomatik tarih/saati kapat.
- Hesaplanmış sütunları mümkünse Power Query'ye ya da kaynağa taşı.
Ölçü ölçmek
- Performans Analizi (İyileştir (Optimize) sekmesi; Görünüm sekmesinden de açılır): Her görselin DAX sorgu süresi, görsel çizim süresi ve “diğer” süresi. Yavaş görselin sorgusunu kopyalayabilirsin.
- DAX Studio: Ücretsiz araç. Sorgu planı, depolama motoru (SE) ve formül motoru (FE) sürelerini gösterir. VertiPaq Analyzer ile tablo ve sütun boyutlarını görürsün.
- Best Practice Analyzer (Tabular Editor): Modeli kurallara göre denetler.
DAX alışkanlıkları
| Yerine | Bunu yaz | Neden? |
|---|---|---|
FILTER(Satislar, Satislar[Kanal] = "Web") | Satislar[Kanal] = "Web" | Tüm tabloyu satır satır taramak yerine tek sütunda filtre |
a / b | DIVIDE(a, b) | Sıfıra bölme güvenli; daha okunur |
| Aynı ifadeyi iki kez yazmak | VAR | Bir kez hesaplanır |
SUMX(Satislar, [Ölçü]) | SUMX(VALUES(Urunler[Urun]), [Ölçü]) | Daha az bağlam geçişi |
IFERROR ile hatayı gizlemek | Hatanın kaynağını düzeltmek | IFERROR motoru yavaşlatır, hatayı saklar |
| Çift yönlü ilişki | Gerektiğinde CROSSFILTER ile ölçüde | Belirsizlik ve gereksiz filtre yayılımı |
Büyük veri için
- Artımlı yenileme: Yalnızca son günleri yeniler, geçmiş bölümleri dokunmadan bırakır.
- Toplamalar (aggregations): Özet tablo Import, ayrıntı DirectQuery. Motor uygun olanı seçer.
- Direct Lake: Fabric'te kopyalama olmadan Import'a yakın hız.
Bir sütunun bedelini ölçmek: kardinalite
Anadolu Market'in modeli büyüdükçe dosya şişiyor ve yenileme uzuyor. İlk soru “hangi tablo büyük?” değil, “hangi sütun pahalı?” olmalı. VertiPaq her sütunu ayrı sıkıştırır; bir sütunun boyutunu en çok farklı değer sayısı (kardinalite) belirler. Bunu ölçmenin en hızlı yolu tek satırlık bir sorgudur:
EVALUATE
ROW(
"SatirNo", DISTINCTCOUNT(Satislar[SatirNo]),
"SiparisNo", DISTINCTCOUNT(Satislar[SiparisNo]),
"Tarih", DISTINCTCOUNT(Satislar[Tarih]),
"Tutar", DISTINCTCOUNT(Satislar[Tutar]),
"MusteriNo", DISTINCTCOUNT(Satislar[MusteriNo]),
"UrunNo", DISTINCTCOUNT(Satislar[UrunNo]),
"Durum", DISTINCTCOUNT(Satislar[Durum]),
"Kanal", DISTINCTCOUNT(Satislar[Kanal])
)
1.620 satırlık Satislar tablosunda sonuç: SatirNo 1.620, SiparisNo 910, Tarih 533, Tutar 357, MusteriNo 136, UrunNo 38, Durum 4, Kanal 3. SatirNo her satırda farklıdır: sözlüğü tablo kadar büyüktür ve art arda tekrar olmadığı için tekrar uzunluğu kodlaması (RLE) hiçbir şey kazandırmaz. Kanal ise 3 değerle neredeyse bedavadır. Gerçek bir modelde aynı oranlar milyonlarca satırla çarpılır.
| Sütun tipi | Tipik kardinalite | Karar |
|---|---|---|
| Satır kimliği, GUID, açıklama metni | Satır sayısı kadar | Raporda kullanılmıyorsa kaldır; detay gerekiyorsa ayrı bir detay sorgusu/sayfalandırılmış rapor |
| Sipariş no, fatura no | Yüksek | Sayım için gerekliyse tut ([Sipariş Sayısı]), metin değil tam sayı olsun |
| Tarih-saat | Çok yüksek | Tarih ve saat olarak böl, saniyeyi at |
| Tutar, fiyat | Orta-yüksek | Gereksiz ondalığı azalt; satırda hesaplanabiliyorsa (Adet × Fiyat) iki ucu tut, sonucu ölçüde hesapla |
| Kanal, durum, kategori | Çok düşük | Sorun değil |
Tam sayı sütunları sözlük yerine değer kodlaması (value encoding) ile de saklanabilir; metin anahtar yerine tam sayı anahtar bu yüzden ucuzdur. Satır sırası da önemlidir: aynı değerler art arda geldikçe RLE daha iyi çalışır. VertiPaq sıralamayı kendisi seçer; sen kardinaliteyi düşürmeye odaklan.
Tarih-saat ve ondalık: kardinaliteyi kırmak
Saniye hassasiyetindeki bir zaman damgası bir yılda 31.536.000 farklı değer alabilir. Aynı bilgi tarih (365 değer) ve dakika düzeyinde saat (1.440 değer) olarak iki sütuna bölünürse toplam farklı değer 1.805'e iner. Bu oyun alanının WebOlaylari tablosu bu yüzden Tarih ve Saat sütunlarını ayrı tutar. Bölmeyi Power Query'de yap; DAX hesaplanmış sütunuyla bölersen orijinal sütun modelde kalır ve kazanç olmaz.
Ondalık sayılarda da benzer bir kazanç vardır. Kuruş hassasiyeti yeten bir tutarı “Sabit ondalık sayı” (Fixed decimal) türüne almak hem boyutu hem kayan nokta yuvarlama sürprizlerini azaltır. Oran sütunlarını (ör. 0,1537291) iki-dört basamağa yuvarlamak kardinaliteyi ciddi düşürür; ama yuvarlamayı iş biriminin onayıyla yap.
Otomatik tarih/saat: görünmeyen tablolar
Otomatik tarih/saat açıkken Power BI modeldeki her tarih sütunu için gizli bir tarih tablosu oluşturur. Bu modelde Satislar[Tarih], Satislar[TeslimTarihi], Musteriler[KayitTarihi], Musteriler[IlkSiparis], Calisanlar[IseGiris], projelerin üç tarih sütunu… her biri ayrı bir gizli tablo demektir. Her gizli tablo, sütundaki en eski ve en yeni yılı tam yıllarla kapsar; 1950 doğumlu bir kayıt varsa 70 yıllık bir tablo oluşur.
- Kapatma yolu: Dosya → Seçenekler ve ayarlar → Seçenekler → Geçerli Dosya → Veri Yükü → Otomatik tarih/saat. Yeni dosyalar için Genel bölümündeki aynı ayarı da kapat.
- Önce: kendi
Tarihtablon “Tarih tablosu olarak işaretle” (Mark as date table) ile işaretlenmiş olmalı. - Yan etki: otomatik hiyerarşiyi (
Tarih.Yıl,Tarih.Ay) kullanan görseller bozulur; bunlarıTarihtablosunun sütunlarıyla yeniden kur. Hızlı ölçüler de otomatik hiyerarşiye yazılmışsa gözden geçir.
Performans Analizi'ni okumak
Performans Analizi (Performance analyzer) her görsel için üç süre verir. Kaydı başlat, Görselleri yenile de ve yavaş görseli aç:
| Yüksek olan | Anlamı | İlk bakılacak yer |
|---|---|---|
| DAX sorgusu | Model ya da ölçü yavaş | Sorguyu kopyala, DAX Studio'da Server Timings (DAX optimizasyonu dersi) |
| Görsel görüntüleme | Çizim yavaş: çok nokta, ağır özel görsel, çok satırlı tablo | Nokta sayısını azalt, ilk N, özet görsel + detay sayfası |
| Diğer | Görsel sırasını bekliyor; sayfadaki başka görseller önce çalışıyor | Sayfadaki görsel sayısını azalt |
İlk ölçüm soğuk önbellekle yapılmadıysa sayılar yanıltır: ikinci yenilemede DAX süresi önbellekten gelir. Yavaş görselin süresini en az iki kez, aynı koşulla ölç.
Sayfa ve görsel sayısı
Her görsel en az bir sorgu gönderir; dilimleyiciler, kartlar ve metin kutusundaki dinamik başlıklar dahil. 30 görselli bir sayfada her biri 80 ms bile sürse sorgular sırayla beklediği için kullanıcı birkaç saniye bekler; Performans Analizi'nde bu bekleme “Diğer” sütununda birikir. Altı ayrı kart yerine çok değerli tek bir kart, on dilimleyici yerine filtre bölmesi, ayrıntı için ikinci bir sayfa kullan. Çapraz filtreleme her tıklamada sayfadaki tüm görselleri yeniden sorgulatır: gereksiz etkileşimleri “Etkileşimleri düzenle” ile kapat. Dilimleyicileri “Uygula” düğmesine bağlamak için Seçenekler → Geçerli Dosya → Sorgu azaltma (Query reduction) ayarlarını kullan.
Anti-kalıp: her soruya hesaplanmış sütun
“Hafta sonu satışı” istenince sık görülen çözüm, Satislar'a HaftaSonuMu hesaplanmış sütunu eklemektir. Bu sütun her yenilemede yeniden hesaplanır, olgu tablosunda yer kaplar ve Tarih tablosunda zaten olan bilgiyi kopyalar.
-- Kaçın: olgu tablosunda hesaplanmış sütun HaftaSonuMu = RELATED(Tarih[HaftaSonu])
Doğru yer boyut tablosudur: Tarih[HaftaSonu] 1.096 satırda yaşar, filtre ilişki üzerinden Satislar'a iner. Ölçüde yalnızca bir sütun filtresi yazılır ve sonuç (bu modelde hafta sonları 341.997,65 ₺ net satış) aynı çıkar. Kural: Satır başına bilgi boyuttan geliyorsa boyutta kalsın; olguda yalnızca anahtarlar ve sayılar dursun.