“Kurumsal model” dersinde depolama modlarını, toplamaları ve artımlı yenilemeyi kısaca tanıdın; “Veri bağlantıları” dersinde katlamanın neden önemli olduğunu gördün. Bu ders o başlıkları bir üretim projesi gibi ele alıyor: mekanizma, sayılar, tuzaklar ve lisans gerçekleri.
Senaryo: Anadolu Market büyüdü
Bu uygulamadaki Satislar tablosu 1.620 satırdır. Şimdi şirketin beş yılda 900 milyon satış satırına ulaştığını düşün. Üç şikâyet var:
- Gece yenilemesi dört saat sürüyor ve bazen zaman aşımına düşüyor.
- Model belleğe sığmıyor; kapasite yöneticisi uyarı gönderiyor.
- Satış direktörü bugünün satışlarını canlı görmek istiyor.
Her şikâyetin ayrı bir aracı var: artımlı yenileme süreyi, büyük model biçimi ve toplamalar belleği ve sorgu hızını, hibrit tablo tazeliği çözer. Yanlış araç seçmek, bir sorunu çözerken diğerini büyütür.
Artımlı yenileme: mekanizma
Power Query’de tam olarak RangeStart ve RangeEnd adlı iki Tarih/Saat parametresi oluşturulur. Adlar ayrılmıştır ve büyük-küçük harfe duyarlıdır. Olgu tablosu bunlarla filtrelenir:
let
Kaynak = Sql.Database("sql-anadolu", "SatisDW"),
Satis = Kaynak{[Schema = "dbo", Item = "Satislar"]}[Data],
Filtre = Table.SelectRows(Satis, each [Tarih] >= RangeStart and [Tarih] < RangeEnd)
in
Filtre
Yayımladıktan sonra Service bu parametrelere kendi değerlerini verir ve her bölüm (partition) için ayrı bir sorgu gönderir. Filtre kaynağa katlanırsa her bölüm sorgusu yalnızca kendi satırlarını çeker. Katlanmazsa her bölüm tüm tabloyu indirir ve filtreyi ağ geçidinde ya da Service’te uygular. Learn bunun yenilemeyi yavaşlattığını ve kaynakları tükettiğini, yani artımlı yenilemenin amacını boşa çıkardığını söyler.
Sınır kuralı: büyük-eşit ve küçük
Başta >=, sonda < kullanılır. İki uçta da <= kullanırsan gece yarısındaki bir satır iki komşu bölüme birden girer ve çift sayılır. Bu hata toplamı yalnızca biraz şişirdiği için uzun süre fark edilmez.
Politika ve bölümler
Tabloya sağ tık → Artımlı yenileme. Örnek politika: “Son 3 yılı arşivle, son 10 günü artımlı yenile, yalnızca tam günler”. Service eski dönemleri yıl bölümlerinde, yakın dönemleri daha küçük bölümlerde tutar; her yenilemede yalnızca son 10 günün bölümleri yeniden yüklenir.
Bu uygulamanın verisiyle bir benzetim: yenileme 1 Ocak 2025 sabahı çalışıyor ve “yalnızca tam günler” açık. Pencere 22–31 Aralık 2024’tür. Motorla sayınca bu pencerede 31 satır ve 25.897,20 net satış var; dokunulmayan arşivde 1.589 satır kalıyor. Yani her gece verinin yaklaşık %1,9’u işleniyor. 900 milyon satırlık modelde oran benzer kalırsa dört saatlik yenileme dakikalara iner.
| Ayar | Ne yapar? | Dikkat |
|---|---|---|
| Arşivle | Tutulacak geçmiş dönem | Daha eskisi modelden düşer |
| Artımlı yenile | Her seferinde yeniden yüklenen dönem | Geriye dönük düzeltmeler (iade, iptal) bu pencereye sığmalı |
| Yalnızca tam günler | Bugünün yarım gününü yüklemez | Gerçek zamanlı bölüm için zorunlu; saat dilimi varsayılan UTC |
| Veri değişikliklerini algıla | Değişmemiş bölümleri atlar | Bölümleme sütunundan farklı bir “son güncelleme” sütunu ister |
Anadolu Market’te iadeler satıştan 30 gün sonra kaydediliyorsa 10 günlük pencere yetmez: iade edilen satır arşiv bölümünde eski hâliyle kalır. Pencereyi iş kuralına göre seç.
Sık hatalar
- Tür uyuşmazlığı: Kaynak sütun tarih, parametreler tarih/saat. Kaynak tamsayı anahtar (20241231) ise parametreyi
yyyyMMddbiçimli tamsayıya çevirmek gerekir. - Filtre sırası: Filtre, kaynak adımından hemen sonra gelmeli. Önce
Table.Buffer, birleştirme ya da özel sütun eklemek katlamayı bozabilir. - Yerel SQL sorgusu: Yalnızca saf Import politikasında
EnableFolding=falseile mümkündür; gerçek zamanlı bölümle olmaz. - Desktop’tan yeniden yayımlamak: Var olan bölümleri ve veriyi siler. Yayımladıktan sonra modeli .pbix olarak geri indiremezsin. Şema değişikliklerini ALM Toolkit gibi araçlarla yalnızca meta veri olarak dağıt.
- İlk yenileme: Bütün geçmişi yükler, uzun sürer; elle başlat ve izle.
Hibrit tablo: gerçek zamanlı son bölüm
Politikadaki “En son verileri DirectQuery ile gerçek zamanlı al” seçeneği, yenileme penceresinden sonraki dönem için bir DirectQuery bölümü ekler. Tablo artık hibrittir: geçmiş bellekte, bugün kaynakta. Satış direktörünün “bugünü canlı göster” isteği böyle karşılanır.
- “Yalnızca tam günler” açık olmalıdır.
- Katlanmayan dönüşümlere izin verilmez; bütün bölümler tek bir veri kaynağını kullanmalıdır.
- Learn’e göre yalnızca Premium, Kullanıcı Başına Premium (PPU) ve Embedded’da vardır; Pro’da yoktur. Bu tür bir model yalnızca Premium çalışma alanına yayımlanabilir.
Mekanizma: “Bu yıl” toplamını isteyen bir görsel için motor bellekteki bölümleri tarar, bugünün bölümü için kaynağa SQL gönderir ve sonuçları birleştirir. Yani her görsel sorgusu kaynağa da gider. Kaynak veritabanı bu yükü kaldırmalı; Dual boyutlar ve toplama tabloları bu yükü azaltır.
Kullanıcı tanımlı toplama tabloları
Toplama tablosu (aggregation), ayrıntı olgu tablosunun daha kaba bir özetidir. Kullanıcı yalnızca ayrıntı tablosunu görür; motor sorguyu özetle cevaplayabiliyorsa özete gider (isabet, hit), cevaplayamıyorsa ayrıntıya düşer (ıska, miss).
Kurulum (Learn’e göre)
- Veri bölmesinde özet tabloya sağ tık → Toplamaları yönet (Manage aggregations). Her sütun için özetleme (Sum, Count, Count table rows, GroupBy), ayrıntı tablosu ve ayrıntı sütunu seçilir.
- Ayrıntı tablosu DirectQuery olmalıdır, Import olamaz. Özet tablo en hızlı Import’tadır; Import’a alındıktan sonra geri çevrilemez.
- Özet Import olunca Power BI ilişkili boyutları Dual yapmayı önerir. İlişki tabanlı isabet için ilişkiler “normal” (regular) olmalıdır.
- Birden çok özet varsa öncelik (precedence) değeri yüksek olan önce denenir. Zincirleme toplama (özetin özeti) yoktur; ayrıntı tablosu her zaman temel tablodur.
- İlişki tabanlı toplamalar yıldız şemaya, GroupBy tabanlı toplamalar ilişkisi olmayan düz büyük tablolara uygundur.
Motorla bir benzetim
Ay × kategori düzeyinde bir özet tablo:
EVALUATE
SUMMARIZECOLUMNS(
Tarih[YilAy], Kategoriler[Kategori],
"Tutar", SUM(Satislar[Tutar]),
"Satir", COUNTROWS(Satislar)
)
Sonuç 199 satırdır; ayrıntı 1.620 satır. Gerçek modelde oran çok daha çarpıcıdır: 900 milyon satır birkaç bin satıra iner. Özet ile ayrıntı aynı sonucu vermeli; bunu sorguyla doğrularsın:
EVALUATE
VAR o = SUMMARIZECOLUMNS(Tarih[YilAy], Kategoriler[Kategori], "Tutar", SUM(Satislar[Tutar]))
RETURN ROW("OzetTutar", SUMX(o, [Tutar]), "AyrintiTutar", SUM(Satislar[Tutar]), "OzetSatir", COUNTROWS(o))
İki tutar da 1.346.189,85 çıkar. Bu toplamı [Toplam Satış] ölçüsüne aittir.
Anti-kalıp: ölçünün filtresi özette yok
Raporlar ise [Net Satış] kullanıyor ve bu ölçü Satislar[Durum] <> "İptal" filtresi uygular. Özet tabloda Durum sütunu yoksa motor bu filtreyi özetle cevaplayamaz ve her sorgu ayrıntıya düşer. Toplama tablosu vardır ama hiç kullanılmaz. Çözüm Durum’u özetin GroupBy sütunlarına eklemektir: özet 431 satıra çıkar, iptaller dışarıda bırakılınca 1.250.772,45 verir, yani [Net Satış] ile aynı. Kural: özetin taneciği (grain), raporlardaki ölçülerin kullandığı bütün sütunları kapsamalı.
Toplanamayan ölçüler
- Ortalama: Learn’e göre
AVERAGEtoplam / sayıya katlanır, bu yüzden özette hem Sum hem “Count table rows” bulunmalı. OrtalamayıDIVIDE(SUM(…), COUNTROWS(…))diye yazmak niyeti açık eder. - Tekil sayım: 2024’te tekil müşteri 123, ama aylık tekil müşterileri toplarsan 509 çıkar. Tekil sayım özetten toplanamaz; isabet için sayılan sütun (MusteriNo) özette GroupBy olmalıdır. Bu da özeti büyütür.
Güvenlik ve tazelik
- RLS ifadesi hem özeti hem ayrıntıyı filtrelemeli. Yalnızca özeti filtreleyen RLS’ye izin verilmez; yalnızca ayrıntıyı filtreleyen RLS çalışır ama sorgular isabet almaz.
- Özet Import, ayrıntı DirectQuery olduğu için özet bayatlarsa aynı soru iki farklı sayı verebilir. Özetin yenilemesini kaynağın yükleme zamanına bağla.
İsabeti nasıl ölçersin?
- Learn, SQL Server Profiler’da Query Processing → Aggregate Table Rewrite Query olayını önerir. Olayın JSON çıktısındaki
matchingResultisabeti,dataRequestistenen sütunları,mappingeşlenen özet sütunlarını gösterir. - Pratik ilk kontrol: Performans Analizi’nde (Performance Analyzer) görselin satırında DirectQuery süresi görünüyorsa sorgu kaynağa gitmiştir.
- Test listesi: her rapor sayfasındaki her görseli bir kez çalıştır, ıskaları yaz, özet taneciğini ya da ölçüyü düzelt.
Otomatik toplamalar
Otomatik toplamalar, son 7 günün sorgu günlüğünden öğrenerek System özet tablolarını kendisi oluşturur ve günceller. Ayarı anlam modelinin Service’teki Ayarlar sayfasındadır; bir kaydırıcıyla önbellekten cevaplanacak sorgu yüzdesi seçilir.
- Premium kapasite, PPU ve Embedded gerekir; Pro’da yoktur. Yalnızca Service’te çalışır, Desktop’ta yoktur.
- DirectQuery modelleri ve bileşik modellerin DirectQuery kısmı içindir. Kaynaklar arasında Azure SQL Database, SQL Server 2019 ve sonrası, Snowflake, Databricks, BigQuery ve Redshift sayılır.
- Eğitim günün ilk zamanlanmış yenilemesinde çalışır ve 60 dakika sınırı vardır. Yüzde arttıkça kaynağa giden eğitim sorguları da artar.
- Hesaplanmış sütunlar dikkate alınmaz; yalnızca hibrit tablolardan oluşan modellerde açılmamalıdır; özellik açıkken .pbix indirilemez.
Ne zaman hangisi? Sorgu kalıpları belli ve az sayıdaysa kullanıcı tanımlı özet daha öngörülebilirdir. Kullanıcılar çok farklı açılardan sorguluyorsa otomatik toplama emek kazandırır.
Bileşik model ve depolama modu seçimi
Toplamaların isabet alması, ilişkilerin normal kalmasına bağlıdır. Learn’in tek kaynaklı model için verdiği kural:
| Çok tarafı | Bir tarafı normal ilişki için |
|---|---|
| Dual | Dual |
| Import | Import ya da Dual |
| DirectQuery | DirectQuery ya da Dual |
Yani boyutlar hem Import özete hem DirectQuery ayrıntıya bağlanacaksa tek doğru seçim Dual’dır. Boyut Import kalırsa DirectQuery ayrıntıyla ilişkisi sınırlı (limited) olur. Çoka çok ilişkiler her zaman sınırlıdır; farklı kaynaklar arasındaki ilişki yalnızca iki taraf da Import ise normaldir.
| Tablo | Mod | Neden |
|---|---|---|
| Satislar (900 M satır) | DirectQuery (hibritse son bölüm) | Belleğe alınmaz; ayrıntı sorguları için |
| Satış özeti (ay × kategori × durum) | Import, gizli | Raporların çoğu buradan cevaplanır |
| Tarih, Urunler, Kategoriler, Musteriler | Dual | İki tarafa da normal ilişki |
| Küçük bağımsız arama tabloları | Import | DirectQuery tabloya bağlı değilse |
Büyük model biçimi ve XMLA ile bölüm yenileme
Büyük anlam modeli depolama biçimi (Large semantic model storage format), modelin varsayılan 1 GB sınırını aşıp kapasitenin izin verdiği boyuta kadar büyümesini sağlar. Learn’e göre Fabric F, Premium P, Embedded A SKU’larında ve PPU’da vardır; ayrılmış kapasitedeki Pro çalışma alanlarında 1 GB ile sınırlıdır. Service’te modelin Ayarlar → Büyük anlam modeli depolama biçimi anahtarıyla açılır; Premium çalışma alanı bunu yeni modeller için varsayılan yapabilir. 1 GB’ı aşacak artımlı yenileme modellerinde ilk yenilemeden önce açılmalıdır. Ayrıca XMLA yazma performansını iyileştirdiği için küçük modellerde de önerilir.
Bellek gerçeği: yenileme sırasında model geçici olarak daha fazla bellek ister. Kapasitenin yarısına yaklaşan bir model tam yenilemede belleği aşabilir; tek tek bölüm yenilemek bu yüzden önemlidir.
XMLA uç noktası varsayılan olarak salt okunurdur; yazma işlemleri için kapasite ayarından Okuma Yazma açılır. SQL Server Management Studio’da TMSL ile tek bir bölüm yenilenebilir:
{
"refresh": {
"type": "full",
"objects": [
{ "database": "AnadoluSatis", "table": "Satislar", "partition": "2024Q4" }
]
}
}
| Yenileme yolu | Süre sınırı (Learn) |
|---|---|
| Pro, zamanlanmış | 2 saat |
| Premium, zamanlanmış | 5 saat |
| XMLA uç noktası | Sınır yok; günlük 48 yenileme sınırına da sayılmaz |
Çok büyük modellerde “önyükleme” (bootstrapping) yapılır: nesneler veri yüklenmeden oluşturulur, sonra geçmiş bölümler tek tek doldurulur. Eski bir bölümü (ör. düzeltilmiş 2022 verisi) yeniden yüklemek de XMLA (SSMS ya da TMSL betiği) veya gelişmiş yenileme REST API’sinin objects parametresiyle yapılır (Premium, PPU, Embedded). Unutma: Desktop’ta yazılmış bir modelde XMLA ile yazma yapılınca model artık .pbix olarak indirilemez; kaynak dosyanı sakla.
Direct Lake ile karşılaştırma ve karar tablosu
Veri Fabric’te Delta tablolarındaysa “Kurumsal model” dersindeki Direct Lake seçeneği çoğu artımlı yenileme işini ortadan kaldırır: veri kopyalanmaz, “yenileme” tablonun yeni sürümüne bakmaktır (çerçeveleme). Bedeli, verinin önce bir göl evine ya da ambara taşınmış olmasıdır.
| Seçenek | Tazelik | Sorgu hızı | Kaynak yükü | Ne zaman? |
|---|---|---|---|---|
| Import + artımlı yenileme | Son yenileme | En iyi | Yenilemede düşük | Gecelik tazelik yeterli, kaynak ilişkisel |
| Hibrit tablo | Bugün canlı | Geçmiş hızlı, bugün kaynağa bağlı | Her sorguda biraz | “Bugünü göster” isteği, Premium/PPU |
| Bileşik + toplama | Ayrıntı canlı, özet son yenileme | İsabette hızlı, ıskada yavaş | Iskalarda yüksek | Veri belleğe sığmıyor, sorgular çoğunlukla özet |
| Direct Lake | Delta’nın son sürümü | Import’a yakın | Yok (OneLake okunur) | Veri zaten Fabric’te |
| Saf DirectQuery | Canlı | Kaynağa bağlı | Her sorguda | Saniyeler önemli, kaynak çok güçlü |
Lisans özeti (Learn’e göre)
| Özellik | Pro | PPU | Premium / Fabric kapasitesi |
|---|---|---|---|
| Artımlı yenileme | Var | Var | Var |
| Gerçek zamanlı DirectQuery bölümü | Yok | Var | Var |
| Büyük model biçimi | Yalnızca ayrılmış kapasitede, 1 GB | Var | Var |
| XMLA okuma-yazma | Yok | Var | Var |
| Otomatik toplamalar | Yok | Var | Var |
Kontrol listesi
- RangeStart/RangeEnd tarih/saat mi, filtre kaynak adımından hemen sonra mı, katlandığı doğrulandı mı?
- Filtre
>=ve<mı? Yenileme penceresi geriye dönük düzeltmeleri kapsıyor mu? - 1 GB’ı aşacak modelde büyük model biçimi ilk yenilemeden önce açıldı mı?
- Özet tablonun taneciği raporlardaki ölçülerin bütün filtre sütunlarını kapsıyor mu? İsabet Profiler ya da Performans Analizi ile ölçüldü mü?
- Boyutlar Dual mı? RLS hem özeti hem ayrıntıyı filtreliyor mu?
- Şema değişikliği yayımlamayla değil, meta veri dağıtımıyla mı yapılıyor? Kaynak .pbix saklanıyor mu?
- Veri Fabric’teyse Direct Lake değerlendirildi mi?