Power Query i incremental refresh: jak zaprojektować parametry, żeby odświeżanie nie mieliło danych

Praktyczny przewodnik po incremental refresh w Power BI/Fabric: projekt RangeStart/RangeEnd, query folding, partycjonowanie, retention vs refresh i checklisty, by uniknąć pełnych przeliczeń.
22 maja 2026
blog

1. Czym jest incremental refresh w Power BI/Fabric i kiedy ma sens

Incremental refresh (odświeżanie przyrostowe) to mechanizm, który pozwala aktualizować w Power BI/Fabric tylko część danych w modelu — zwykle najnowszy zakres czasu — zamiast przeładowywać całą tabelę od zera przy każdym odświeżeniu. W praktyce dane są logicznie dzielone na zakresy czasowe, a odświeżanie obejmuje tylko te „nowsze” fragmenty, które realnie mogą się zmieniać, podczas gdy starsze pozostają nietknięte.

Najważniejsza intuicja jest prosta: jeśli Twoje dane rosną w czasie i historyczne rekordy są stabilne, pełny refresh marnuje zasoby, bo za każdym razem przelicza to, co już dawno jest „zamrożone”. Incremental refresh przenosi ciężar obliczeń na to, co nowe lub potencjalnie korygowane.

Co to daje (na poziomie efektu, bez wchodzenia w implementację)

  • Krótsze okna odświeżania — mniej danych do pobrania i przetworzenia.
  • Mniejsze obciążenie źródeł — ograniczenie zapytań do wąskiego wycinka czasu.
  • Stabilniejsze odświeżenia — niższe ryzyko timeoutów i błędów przy dużych wolumenach.
  • Lepsza skalowalność — model może rosnąć w czasie bez proporcjonalnego wzrostu kosztu odświeżenia.

Kiedy incremental refresh ma sens

Odświeżanie przyrostowe jest szczególnie uzasadnione, gdy spełniony jest co najmniej jeden z poniższych warunków:

  • Duże tabele faktów, które rosną codziennie/tygodniowo/miesięcznie i z czasem stają się zbyt ciężkie do pełnego odświeżania.
  • Naturalny wymiar czasu w danych (transakcje, zdarzenia, logi, pomiary), gdzie zapisy są „dopisywane” i tylko ostatni okres bywa korygowany.
  • Ograniczone okno serwisowe na odświeżenia (np. raport ma być gotowy rano), a pełny refresh trwa zbyt długo.
  • Ograniczenia po stronie źródła (limity API, obciążone bazy, DWH współdzielony), gdzie chcesz minimalizować transfer i koszt zapytań.
  • Wymóg częstych odświeżeń dla nowych danych, bez konieczności ruszania całej historii.

Kiedy incremental refresh zwykle nie pomoże (albo nie jest priorytetem)

  • Małe modele, gdzie pełny refresh trwa krótko i nie stanowi problemu operacyjnego.
  • Dane często zmieniają się w całym horyzoncie (masowe korekty historyczne, przeliczenia wstecz) — wtedy „przyrostowość” traci sens, bo i tak trzeba często odświeżać dużą część historii.
  • Brak stabilnej kolumny czasu, po której da się sensownie wyznaczyć zakresy (lub czas jest generowany/transformowany w sposób utrudniający filtrowanie).
  • Transformacje wymagające pełnego przeliczenia niezależnie od zakresu dat (np. logika oparta o globalne agregacje), przez co zysk z przyrostu może być ograniczony.

Jak myśleć o incremental refresh w kontekście Power BI vs Fabric

W ujęciu koncepcyjnym mechanizm jest ten sam: chodzi o ograniczenie przetwarzania do „ruchomego okna” danych i pozostawienie reszty w spokoju. Różnice między Power BI i Fabric dotyczą głównie tego, gdzie dane są przechowywane i jak wygląda operacjonalizacja odświeżania, ale cel pozostaje identyczny: odświeżać tylko to, co musi być odświeżone, aby raporty były aktualne bez niepotrzebnego „mielenia” całej historii.

2. Projekt parametrów RangeStart/RangeEnd: typy danych, strefy czasowe, testowanie i dobre praktyki

Parametry RangeStart i RangeEnd to „ramy czasowe”, które incremental refresh wykorzystuje do wyznaczenia, jakie fragmenty danych mają zostać odświeżone. Ich poprawny projekt decyduje o tym, czy odświeżanie będzie przewidywalne i szybkie, czy będzie kończyć się pełnym przemiałem danych albo niestabilnymi wynikami. Piszemy o tym, bo uczestnicy szkoleń Cognity często sygnalizują, że jest to dla nich realne wyzwanie w pracy. Najczęściej problemy nie wynikają z samej polityki odświeżania, tylko z błędnego typu danych, niejednoznacznej strefy czasowej lub trudnych do odtworzenia warunków testowych.

Typ danych: konsekwencja ponad wszystko

Najważniejsza zasada brzmi: parametry i kolumna, po której filtrujesz, muszą „mówić tym samym językiem czasu”. W praktyce oznacza to spójność między:

  • typem parametru (data vs data i godzina),
  • typem kolumny w źródle (np. data, datetime, datetime2),
  • semantyką wartości (czy to początek dnia, konkretny moment, czy data bez czasu).

Jeśli źródłowa kolumna przechowuje znacznik czasu (moment), parametry również powinny być projektowane jako data i godzina. Jeśli dane są dzienne i naturalnym kluczem jest data, parametry jako data mogą być wystarczające, ale tylko wtedy, gdy filtr rzeczywiście działa na dacie, a nie na „dacie wyciągniętej z datetimu” w trakcie transformacji.

Warto też trzymać się prostego kontraktu: RangeStart jest inkluzywny, RangeEnd ekskluzywny. To ułatwia myślenie o granicach (brak duplikatów na styku partycji) i ogranicza ryzyko „dziur” w danych, gdy odświeżasz kolejne okna.

Strefy czasowe: wybierz jedną prawdę i trzymaj się jej

Incremental refresh jest szczególnie wrażliwy na sytuacje, w których w jednym miejscu operujesz czasem lokalnym, a w innym UTC. Najbezpieczniej jest przyjąć jedną konwencję dla całego przepływu:

  • UTC end-to-end (źródło, parametry, filtr, model) – zwykle najłatwiejsze do utrzymania i odporne na zmiany czasu (DST),
  • albo czas lokalny end-to-end – jeśli biznes operuje wyłącznie lokalnie i źródła są spójne, ale wymaga to większej dyscypliny przy integracjach.

Ryzykowne jest mieszanie podejść, np. gdy źródło zapisuje UTC, a parametry są interpretowane jako lokalne „od północy do północy”. Wtedy granice okien mogą się przesuwać, a rekordy z okolic zmiany czasu (DST) potrafią wypaść z okna lub pojawić się w nim podwójnie. Dobra praktyka to jasne nazewnictwo i dokumentacja: jeśli operujesz na UTC, niech to wynika wprost z opisu parametru i definicji kolumny czasowej.

Zakres wartości i semantyka okna

Parametry powinny odzwierciedlać naturalny sposób, w jaki dane „przyrastają” i „zmieniają się w czasie”. Przykładowo:

  • dla danych transakcyjnych z wysoką częstotliwością sensownie jest myśleć o oknach godzinowych lub dziennych, ale parametry nadal powinny reprezentować moment, nie tylko datę,
  • dla danych dziennych parametry jako data mogą działać, o ile nie dokonujesz po drodze konwersji typu, która rozmywa granicę (np. obcinanie czasu w trakcie transformacji).

Istotne jest także, by parametry nie były „sprytne”. Powinny być proste, deterministyczne i stabilne. Unikaj projektowania ich tak, by zależały od bieżącego czasu, kontekstu użytkownika lub innych zmiennych środowiskowych, bo utrudnia to reprodukcję zachowania podczas publikacji i późniejszego utrzymania.

Testowanie: jak sprawdzić, czy filtr działa tak, jak myślisz

Testowanie parametrów nie polega na sprawdzeniu, czy „coś się filtruje”, tylko czy filtr jest:

  • spójny typowo (brak niejawnych konwersji),
  • spójny czasowo (ta sama strefa i semantyka),
  • powtarzalny (te same parametry dają te same wyniki),
  • odporny na granice (rekordy dokładnie na styku RangeStart/RangeEnd zachowują się zgodnie z założeniem inkluzywności/ekskluzywności).

W praktyce warto testować na kilku reprezentatywnych oknach: bardzo wąskim (np. jeden dzień), średnim (np. miesiąc) i takim, który obejmuje „trudne” daty (np. przełom miesiąca, koniec roku, potencjalną zmianę czasu). Jeżeli wyniki między testami a oczekiwaniami się rozjeżdżają, najczęściej winna jest różnica typu (data vs datetime) albo konwersja strefy wykonana w innym miejscu, niż zakładasz.

Dobre praktyki projektowe

  • Ustal kontrakt czasu (UTC lub lokalny) i stosuj go konsekwentnie dla parametru oraz kolumny filtrującej.
  • Dobierz typ parametru do kolumny: jeśli filtrujesz po momencie, parametry też powinny reprezentować moment.
  • Traktuj RangeEnd jako granicę „do, ale nie włącznie”, żeby uniknąć nakładania się okien.
  • Unikaj niejawnych konwersji — jeśli w którymś miejscu czas staje się datą (lub odwrotnie), to zwykle sygnał problemu projektowego.
  • Opisuj intencję: nazwa/komentarz parametru powinny mówić, czy to UTC i jaka jest semantyka granic.
  • Testuj przypadki brzegowe: końce dni, miesięcy, roku oraz okresy zmiany czasu, jeśli używasz czasu lokalnego.

Dobrze zaprojektowane RangeStart/RangeEnd to nie tylko „wymóg incremental refresh”, ale fundament przewidywalności. Jeśli parametry są spójne typowo i czasowo, dalsze decyzje o odświeżaniu i przechowywaniu stają się prostsze, a ryzyko niechcianego pełnego odświeżania wyraźnie maleje.

💡 Pro tip: Ustal jeden „kontrakt czasu” (UTC albo lokalny) i dopasuj typy RangeStart/RangeEnd do kolumny filtrującej (DateTime do znacznika czasu), trzymając zasadę: RangeStart inkluzywny, RangeEnd ekskluzywny. Przetestuj kilka okien (1 dzień, miesiąc, przełom miesiąca/roku i DST), żeby wyłapać duplikaty lub luki na granicach.

3. Projekt modelu i partycjonowania: tabela faktów, kolumna daty, granularity, hybrydowe tabele i real-time

Incremental refresh działa dobrze wtedy, gdy model i tabela, którą odświeżasz, są zaprojektowane „pod czas”. W praktyce oznacza to: odpowiednią tabelę faktów, jednoznaczną kolumnę daty/czasu używaną do partycjonowania oraz granulację dopasowaną do sposobu raportowania i oczekiwanego okna zmian. Ten etap jest o decyzjach architektonicznych — zanim zaczniesz „dopieszczać” parametry czy transformacje.

Tabela faktów jako kandydat do incremental refresh

Incremental refresh najczęściej stosuje się na dużych tabelach faktów (transakcje, zdarzenia, logi, odczyty), gdzie:

  • przyrost danych jest regularny (dopisywanie nowych wierszy w czasie),
  • występują korekty w „niedalekiej przeszłości” (np. zwroty, anulacje, korekty statusów),
  • wolumen danych jest na tyle duży, że pełne odświeżanie jest nieopłacalne czasowo/kosztowo.

Na tabelach wymiarów incremental refresh bywa mniej korzystny, bo zmiany nie zawsze są „czasowe”, a czasem lepsze jest inne podejście (np. pełny reload małego wymiaru). Kluczowe jest, aby partycjonowana tabela miała sensowny „wymiar czasu”, według którego dane da się wiarygodnie porcjować.

Kolumna daty/czasu do partycjonowania: wybór ma znaczenie

W tabeli faktów zwykle masz kilka dat (np. data utworzenia, data księgowania, data modyfikacji). Do incremental refresh potrzebujesz kolumny, która:

  • rośnie w czasie w sposób przewidywalny (nowe wiersze wpadają z nowszą datą),
  • jest stabilna semantycznie (nie „przeskakuje” masowo przy zmianach procesu),
  • odpowiada temu, jak raportujesz i jak chcesz kontrolować okno zmian.

Najczęstszy dylemat to: partycjonować po datę zdarzenia czy po datę modyfikacji. Pierwsza zwykle lepiej pasuje do raportów (sprzedaż za dzień), druga lepiej wspiera wychwytywanie korekt. Często kończy się to kompromisem: partycjonowanie po dacie zdarzenia + odpowiednio dobrane okno „odświeżaj ostatnie N dni”, a w scenariuszach z częstymi korektami — rozważenie strategii hybrydowej (opis poniżej).

Granularity partycji: dzień, miesiąc, godzina?

Granulacja partycjonowania wpływa na:

  • liczbę partycji (i narzut na zarządzanie nimi),
  • czas odświeżania (ile partycji musi się przeliczyć),
  • „precyzję” łapania zmian (jak duży fragment danych odświeżasz przy korektach).

W praktyce najczęściej spotkasz partycje dzienne lub miesięczne. Dzienna granulacja jest sensowna, gdy korekty dotyczą krótkiego okresu i chcesz minimalizować „mielenie” danych. Miesięczna bywa lepsza, gdy dane są umiarkowanie duże, a środowisko ma ograniczenia dotyczące liczby partycji lub gdy proces ładowania jest naturalnie miesięczny.

Granulacja Kiedy ma sens Typowy efekt uboczny
Dzień Duże wolumeny, częste korekty w ostatnich dniach, potrzeba szybkich refreshy Więcej partycji, większa złożoność operacyjna
Miesiąc Stabilne dane, korekty obejmują całe miesiące lub są rzadkie, prostota Każda korekta „ciągnie” większy zakres do przeliczenia
Godzina/minuta Scenariusze near-real-time z wysoką szczegółowością zdarzeń Bardzo dużo partycji; łatwo o narzut i problemy operacyjne

Partycjonowanie a model: relacje, klucze i układ tabel

Incremental refresh dotyczy głównie tabeli faktów, ale jego skuteczność zależy od całego modelu:

  • Relacje: trzymaj fakt w układzie gwiazdy (fakt + wymiary). Ułatwia to optymalizację i redukuje ryzyko niepotrzebnych przeliczeń.
  • Klucze: stabilne klucze w faktach i wymiarach pomagają utrzymać spójność przy odświeżaniu partycji (szczególnie gdy dochodzą korekty).
  • Kolumna partycjonująca: powinna być fizycznie w tabeli faktów (nie „wyliczana” z innej tabeli) i jednoznaczna dla każdego wiersza.

Warto też pamiętać, że niektóre elementy modelu mogą wymuszać większy zakres przeliczeń (np. ciężkie kolumny obliczeniowe w tabeli faktów). Zasada ogólna: im bardziej „ciężkie” obliczenia, tym bardziej opłaca się utrzymać je poza partycjami lub ograniczyć do potrzebnego minimum.

Hybrydowe tabele i real-time: kiedy warto mieszać tryby

Jeżeli część danych musi być „prawie na żywo”, a reszta może być importowana historycznie, rozważ podejście hybrydowe:

  • Import history (większość danych) + DirectQuery dla najnowszego okna — typowo kilka godzin/dni, gdy liczy się świeżość.
  • Dual/Composite w zależności od tego, czy chcesz łączyć agregacje w imporcie z detalem w DirectQuery.

Taka architektura zmniejsza presję na bardzo częste odświeżanie importu, a jednocześnie pozwala raportom widzieć najnowsze rekordy. Kosztem jest większa złożoność: dwa „światy” (cache importu i zapytania do źródła) muszą być spójne definicyjnie (te same klucze, te same miary, przewidywalna logika czasu).

Minimalny wzorzec: fakt z kolumną czasu przygotowaną do partycjonowania

Na poziomie modelu najważniejsze jest, aby tabela faktów miała jednoznaczną kolumnę, po której da się stabilnie filtrować zakres. Przykładowy szkic (tylko idea):

// Fakt: kolumna EventDateTime jest źródłowa i jednoznaczna dla wiersza
// Dodatkowo często utrzymuje się EventDate (bez czasu) do relacji z kalendarzem
EventDate = Date.From([EventDateTime])

Kluczowe jest nie to, jak „ładnie” wygląda kod, tylko by w danych istniała wiarygodna oś czasu oraz by sposób raportowania i sposób partycjonowania nie były ze sobą w konflikcie.

4. Polityka przechowywania i odświeżania: retention vs refresh, okno zmian, dobór pod scenariusze biznesowe

Incremental refresh przestaje „mielić” całe wolumeny danych dopiero wtedy, gdy świadomie rozdzielisz dwie decyzje: ile danych trzymasz w modelu (retention) oraz jak duży wycinek danych odświeżasz (refresh window). Te dwie rzeczy często są mylone, a mają inne cele i inne konsekwencje kosztowe. Zespół trenerski Cognity zauważa, że właśnie ten aspekt sprawia uczestnikom najwięcej trudności — bo intuicyjnie chce się „odświeżać wszystko”, a to zwykle niweczy największe korzyści z partycjonowania.

Retention vs refresh window — o co chodzi i po co to rozdzielać

Retention (okno przechowywania) to zakres historii, który ma być dostępny do analizy w modelu (np. 5 lat). Refresh window (okno odświeżania) to część najnowszych danych, która ma być regularnie przebudowywana, bo tam najczęściej zachodzą korekty, dopisy i opóźnione księgowania (np. ostatnie 7 dni / 1 miesiąc).

Element polityki Cel Wpływ na czas odświeżania Typowe ustawienie
Retention Zapewnić wymagany horyzont analiz Pośredni (większy model = potencjalnie cięższe operacje, ale nie musi wydłużać odświeżania, jeśli odświeżasz tylko fragment) 1–7 lat (zależnie od biznesu/regulacji)
Refresh window Aktualizować obszar, gdzie dane się zmieniają Bezpośredni (im większe okno, tym więcej partycji do przeliczenia) 1–45 dni, czasem 1–3 miesiące

Najczęstszy błąd projektowy: ustawienie okna odświeżania na cały okres przechowywania („żeby było pewnie aktualne”). To praktycznie unieważnia sens incremental refresh.

Okno zmian (change window): skąd wziąć właściwą wartość

Kluczowe pytanie brzmi: jak długo dane mogą się jeszcze zmieniać po dacie zdarzenia? To właśnie definiuje minimalne sensowne okno odświeżania. W praktyce „zmiany” wynikają z kilku mechanizmów:

  • Opóźnione dopływy (late arriving facts) — transakcja trafia do hurtowni po kilku dniach.
  • Korekty — zmiana wartości, statusu, kategorii, przypisań (np. reklamacje, korekty faktur).
  • Reprocesy ETL/ELT — okresowe przeliczenia w źródle mogą modyfikować dane historyczne.
  • Zamykanie okresów — po zamknięciu miesiąca zmiany powinny być rzadkie (albo kontrolowane).

Praktyczna heurystyka: ustaw refresh window nieco szerzej niż deklarowane SLA jakości danych (np. jeśli korekty mogą pojawić się do 14 dni, rozważ 21–30 dni). Zbyt wąskie okno prowadzi do „cichych” rozjazdów raportów, zbyt szerokie — do nadmiernych kosztów i długiego odświeżania.

Dobór polityki pod scenariusze biznesowe

Poniżej typowe wzorce ustawień. Traktuj je jako punkt startowy do rozmowy z właścicielem danych i zespołem utrzymania źródła.

Scenariusz Charakter zmian Retention Refresh window
Sprzedaż detaliczna / e-commerce Zwroty i korekty do kilku–kilkunastu dni, dopływy prawie ciągłe 2–5 lat 7–30 dni
Finanse/księgowość Korekty częste do zamknięcia miesiąca, potem powinny być incydentalne 5–10 lat (często wymogi) 1–2 miesiące (czasem + bufor)
Produkcja/IoT (telemetria) Duży wolumen, mało korekt historycznych, liczy się świeżość Miesiące–2 lata (zależnie od potrzeb analitycznych) 1–7 dni
HR / dane kadrowe Zmiany punktowe, często wprowadzane z opóźnieniem (np. korekty absencji) 3–7 lat 14–60 dni
Logistyka Statusy zmieniają się w trakcie realizacji, po dostawie stabilnie 2–5 lat 14–45 dni

Świeżość danych (freshness) a koszt odświeżania

Polityka odświeżania to kompromis między:

  • Freshness — jak szybko raport ma pokazywać nowe dane,
  • Kosztem — czasem odświeżania, obciążeniem źródła i zasobów po stronie Power BI/Fabric,
  • Ryzykiem niespójności — gdy odświeżasz zbyt wąski wycinek i pomijasz późne korekty.

Jeśli wymagania „prawie real-time” dotyczą tylko ostatnich godzin/dnia, zwykle nie ma powodu, by poszerzać okno odświeżania historii. Lepiej utrzymać krótkie okno zmian i częstszy harmonogram dla najnowszego fragmentu.

Stabilizacja danych: co zrobić, gdy historia jednak się zmienia

Zdarza się, że źródło potrafi modyfikować dane sprzed wielu miesięcy. Wtedy incremental refresh nie rozwiąże problemu sam z siebie — potrzebujesz polityki, która ograniczy lub ucywilizuje te zmiany:

  • Uzgodnij moment „zamrożenia” okresu (np. po zamknięciu miesiąca), po którym korekty są wyjątkami.
  • Wydziel strumień korekt (np. osobna tabela korekt/adjustments), zamiast przepisywać stare rekordy.
  • Wprowadź sygnał zmiany (np. data modyfikacji) i procesy, które kontrolują, jak daleko wstecz mogą sięgać poprawki.

Minimalna checklista do ustawienia polityki

  • Retention: jaki horyzont analityczny jest faktycznie potrzebny (biznes/regulacje)?
  • Okno zmian: jak długo po dacie zdarzenia dane mogą się zmieniać?
  • Buffer: jaki bufor dodajesz na opóźnienia i wyjątki (w dniach/tygodniach)?
  • Harmonogram: jak często muszą odświeżać się dane w oknie zmian?
  • Wyjątki: co robisz, gdy potrzebujesz przeliczyć starszy okres (procedura „backfill”)?

Dobrze ustawiona polityka sprawia, że model przechowuje tyle historii, ile trzeba, ale odświeża tylko to, co realnie „żyje”. To fundament, zanim zaczniesz dopieszczać parametry i techniczne aspekty przetwarzania.

5. Query folding i źródła danych: wymagania, wpływ transformacji, gdzie „łamie się” folding i jak to diagnozować

Incremental refresh opiera się na tym, że filtr czasu (wyliczony z RangeStart/RangeEnd) zostanie „zepchnięty” do źródła danych. W Power Query nazywa się to query folding — silnik M stara się przetłumaczyć kroki zapytania na natywny język źródła (najczęściej SQL) tak, aby ograniczenie danych zadziałało po stronie serwera, a nie lokalnie podczas odświeżania.

Jeśli folding działa, incremental refresh pobiera tylko wymagane partycje/zakresy. Jeśli folding się „łamie”, Power BI może zacząć pobierać zbyt dużo danych (czasem całość) i dopiero potem filtrować, co w praktyce niweluje sens odświeżania przyrostowego.

Wymagania po stronie źródeł danych (co musi „dać się przetłumaczyć”)

Nie każde źródło i nie każdy sposób połączenia umożliwia folding. Najczęściej potrzebujesz:

  • Źródła wspierającego zapytania delegowane (np. relacyjne bazy danych, część konektorów do hurtowni/lakehouse’ów). Pliki (CSV/Excel) z reguły nie mają „serwera zapytań”, więc folding bywa ograniczony lub żaden.
  • Trybu połączenia i konektora, który nie wymusza pobierania danych do klienta przed obróbką (np. natywne konektory vs nietypowe ODBC z ograniczeniami).
  • Możliwości użycia predykatu na kolumnie daty (WHERE na dacie/czasie) w sposób zrozumiały dla źródła.

W praktyce incremental refresh działa najlepiej, gdy tabela faktów jest w źródle, a filtrowanie po dacie może zostać wykonane po stronie serwera na indeksowanej/partycjonowanej kolumnie.

Wpływ transformacji na folding (dlaczego to takie kruche)

Folding jest „łańcuchem”: dopóki kolejne kroki dają się przetłumaczyć, dopóty filtr czasu może zostać złożony w zapytanie źródłowe. Wystarczy jeden krok, którego nie da się złożyć, aby dalsze kroki były liczone lokalnie, a filtr daty przestaje ograniczać pobieranie danych.

Kluczowa zasada: jeśli filtr RangeStart/RangeEnd jest w kroku, który nie foldinguje się do źródła, incremental refresh traci największą część przewagi.

Typowe miejsca, gdzie „łamie się” folding

Poniżej najczęstsze kategorie operacji, które potrafią przerwać folding (zależnie od konektora i źródła):

  • Operacje nieprzekładalne na SQL: złożone funkcje tekstowe, niestandardowe parsowanie, wyrażenia oparte o bieżący czas systemu, rozbudowane funkcje M w kolumnach obliczanych.
  • Zmiana typu lub konwersje dat wykonywane w sposób, który wymaga przeliczenia wartości w kliencie (np. niejednoznaczne parsowanie tekstu do daty, konwersje z użyciem niestandardowych kultur/formatów).
  • Dodawanie kolumn niestabilnych (np. indeksy, rankingi, kolumny zależne od kolejności) przed zastosowaniem filtra czasu.
  • Łączenia (merge) i grupowania w sytuacjach, gdy źródło nie potrafi ich wykonać lub gdy łączysz dane z różnych źródeł (często skutkuje materializacją po stronie Power Query).
  • Użycie funkcji „Table.Buffer” i podobnych technik wymuszających materializację — zazwyczaj celowo wyłącza folding.
  • Odwołania do kroków, które ukrywają źródło (np. pobranie całej tabeli, a potem filtrowanie w kolejnych krokach), jeśli konektor nie potrafi „cofnąć” filtra do źródła.

Jak diagnozować folding (szybkie metody w praktyce)

Diagnostyka powinna odpowiedzieć na dwa pytania: czy filtr czasu jest delegowany oraz w którym kroku folding się urywa.

  • „View Native Query” (Pokaż zapytanie natywne): jeśli opcja jest dostępna dla danego kroku, folding najpewniej działa do tego miejsca. Gdy opcja znika na konkretnym kroku — to dobry kandydat na „breaker”.
  • Porównanie zapytania natywnego: sprawdź, czy w SQL (lub odpowiedniku) pojawia się predykat na dacie (np. WHERE Date >= ... AND Date < ...). Brak predykatu zwykle oznacza, że filtr nie został złożony.
  • Query Diagnostics w Power Query: pozwala zobaczyć, czy do źródła idzie jedno delegowane zapytanie, czy też następuje pobranie dużej porcji danych i obróbka lokalna.
  • Test na skali danych: uruchom odświeżenie z bardzo wąskim oknem (np. 1 dzień) i obserwuj, czy liczba pobieranych wierszy/czas zapytań spada proporcjonalnie. Jeśli nie — najczęściej folding nie działa.

Folding a różne typy źródeł: szybkie porównanie

Typ źródłaSzansa na foldingNajczęstszy problem
Relacyjne bazy danych / hurtownieWysokaTransformacje M nieprzekładalne na SQL, zbyt wczesna materializacja
Lakehouse / pliki w jeziorze (bez warstwy SQL)Średnia do niskiejBrak „serwera zapytań” → filtrowanie po stronie klienta
CSV/ExcelNiskaBrak delegacji; incremental refresh może nie przynieść oczekiwanych oszczędności
API/źródła weboweZależnaBrak wsparcia dla parametrów filtra po stronie API lub ograniczenia paginacji

Minimalny przykład: jak upewnić się, że filtr jest „blisko źródła”

Poniższy wzorzec pokazuje intencję: filtr na dacie powinien być zastosowany jak najwcześniej (o ile krok nadal foldinguje), zanim pojawią się cięższe transformacje.

let
    Source = Sql.Database("SERVER", "DB"),
    Fact = Source{[Schema="dbo", Item="FactSales"]}[Data],
    Filtered = Table.SelectRows(Fact, each [SaleDate] >= RangeStart and [SaleDate] < RangeEnd)
in
    Filtered

To nie gwarantuje foldingu w każdym środowisku, ale ułatwia jego utrzymanie: najpierw delegowalny filtr, dopiero potem kolejne kroki (o ile nadal są delegowalne).

Najważniejsze wnioski dla incremental refresh

  • Incremental refresh „żyje” na query folding: jeśli filtr RangeStart/RangeEnd nie trafia do źródła, odświeżanie będzie mielić dane.
  • Folding jest zależny od konektora i kolejności kroków: identyczne M może foldować w jednym źródle i nie foldować w innym.
  • Diagnozuj na poziomie kroku: znajdź pierwszy krok bez „View Native Query” i traktuj go jako punkt startowy do uproszczeń.
💡 Pro tip: Pilnuj, by filtr na RangeStart/RangeEnd był jak najbliżej źródła i w kroku, który nadal foldinguje — inaczej incremental refresh zacznie pobierać „za dużo” i filtrować dopiero lokalnie. Diagnozuj krok po kroku: znajdź moment, w którym znika „View Native Query”, i sprawdź, czy w zapytaniu natywnym faktycznie pojawia się predykat WHERE na dacie.

6. Jak uniknąć pełnych przeliczeń: zasady transformacji, kolejność kroków, Dataflows/Gen2, materializacja i optymalizacje

Incremental refresh ma sens tylko wtedy, gdy podczas odświeżania Power Query potrafi ograniczyć pracę do wycinka danych (partycji) zamiast przetwarzać całość. W praktyce „pełne przemielenie” najczęściej wynika z dwóch rzeczy: (1) filtr czasu nie jest delegowany do źródła lub (2) kosztowne kroki transformacji wykonywane są przed zawężeniem danych. Poniżej zasady, które pomagają utrzymać odświeżanie przyrostowe jako faktycznie przyrostowe.

6.1. Zasada nadrzędna: najpierw ogranicz dane, potem je „obrabiaj”

Najważniejsza praktyka to układ kroków w Power Query:

  • Najpierw zastosuj filtr na kolumnie czasu (oparty o parametry RangeStart/RangeEnd), najlepiej jak najbliżej kroku Source.
  • Dopiero potem wykonuj cięższe operacje: łączenia (Join), grupowania (Group By), sortowania, dodawania kolumn obliczeniowych, tekstowych parsowań, wywołań funkcji niestandardowych itd.

Jeżeli musisz wykonywać transformacje, które mogą uniemożliwić delegowanie filtra do źródła, rozważ podział na dwa etapy: staging (minimalne zmiany + filtr) oraz curation (logika biznesowa).

6.2. Transformacje „bezpieczne” vs „ryzykowne” (dla uniknięcia pełnych przeliczeń)

Nie wchodząc w szczegóły mechaniki, można przyjąć prostą heurystykę: im bardziej transformacja przypomina standardowe operacje SQL na tabeli, tym większa szansa, że nie wymusi przeliczenia całego zbioru.

Typ kroku Zwykle bezpieczniejsze (mniejsza szansa na pełne przeliczenie) Częściej ryzykowne (łatwiej „złamać” delegowanie)
Filtrowanie Filtr po dacie/czasie na kolumnie źródłowej Filtr po kolumnie utworzonej wcześniej (np. z tekstu)
Kolumny Prosta selekcja/zmiana nazw, rzutowania typów zgodne ze źródłem Złożone kolumny niestandardowe, funkcje użytkownika, parsowanie JSON/HTML
Łączenia Join po kluczach, gdy obie strony są „źródłowe” i proste Join po kluczach wyliczanych, po transformacjach, z niedeterministycznymi kluczami
Agregacje Proste Group By na ograniczonym zbiorze Group By przed filtrem czasu lub po krokach, które wymuszają skan całości

Cel jest praktyczny: utrzymać filtr czasu jako najwcześniejszy i najprostszy krok, aby odświeżanie nie musiało „dotykać” danych poza oknem przyrostu.

6.3. Unikaj „przypadkowej materializacji” i niepotrzebnych skanów danych

Pełne przeliczenia potrafią być skutkiem nie tylko utraty delegowania, ale też nieoptymalnego planu wykonania zapytania. Kilka praktyk, które często pomagają:

  • Ogranicz liczbę kolumn jak najwcześniej (usuń nieużywane kolumny jeszcze przed dalszymi krokami). Mniej danych do przeniesienia i przetworzenia to mniejsze ryzyko, że operacje staną się kosztowne.
  • Unikaj wielokrotnego odwoływania się do tej samej, ciężkiej kwerendy w kilku miejscach modelu. Jeśli ta sama baza/staging jest używana w kilku tabelach, rozważ wspólny etap (np. dataflow) zamiast duplikowania logiki.
  • Nie wymuszaj buforowania „na ślepo” (np. poprzez agresywne używanie mechanizmów, które powodują wczytanie danych do pamięci). Bufor może pomóc w specyficznych przypadkach, ale równie często prowadzi do pełnego pobrania danych i utraty korzyści z przyrostu.

6.4. Dataflows / Dataflows Gen2 jako warstwa odciążająca i stabilizująca

Jeżeli logika transformacji jest rozbudowana, a model ma wykorzystywać incremental refresh, często lepiej jest rozdzielić odpowiedzialności:

  • Dataflow (staging): pobranie ze źródła, minimalne czyszczenie, ujednolicenie typów, wczesny filtr czasu oraz podstawowe, powtarzalne kroki.
  • Semantyczny model: relacje, miary, logika analityczna; w Power Query tylko to, co musi być w modelu.

W praktyce dataflow bywa miejscem, w którym łatwiej „usadzić” transformacje i ograniczyć je do jednego przebiegu, a następnie zasilać nimi różne raporty/dataset’y. Wersje Gen2 dodatkowo pasują do scenariuszy, gdzie potrzebujesz bardziej przewidywalnego przetwarzania i kontroli nad etapami przygotowania danych (zależnie od architektury w Fabric).

6.5. Materializacja po drodze: kiedy warto (i co materializować)

„Materializacja” to świadome zapisanie wyniku pośredniego, zamiast liczenia wszystkiego przy każdym odświeżeniu od zera. W kontekście uniknięcia pełnych przeliczeń najczęściej materializuje się:

  • Warstwę surową/staging po zastosowaniu filtra czasu i podstawowym czyszczeniu.
  • Tabele referencyjne (wymiary, mapowania), które zmieniają się rzadko i nie powinny obciążać odświeżania faktów.

Korzyść jest prosta: odświeżanie przyrostowe „widzi” mniej kroków do wykonania, a ciężka logika nie jest uruchamiana ponownie dla całej historii.

6.6. Szybkie checklisty optymalizacyjne (praktyczne i krótkie)

  • Filtr RangeStart/RangeEnd wstaw jak najwcześniej, na kolumnie czasu ze źródła.
  • Usuń kolumny i wykonaj proste rzutowania typów przed bardziej złożonymi operacjami.
  • Ogranicz Join/Group By do danych już zawężonych czasowo.
  • Nie duplikuj tej samej ciężkiej logiki w kilku zapytaniach; centralizuj ją w staging/dataflow.
  • Testuj na małym oknie czasu, ale weryfikuj też, czy odświeżanie nie „dotyka” historii (objaw: długi czas mimo małego okna).

6.7. Minimalny przykład kolejności kroków w M

Poniższy szkic pokazuje intencję: filtr czasu wcześnie, transformacje później (kod jako punkt odniesienia, nie jako uniwersalny szablon):

let
  Source = Sql.Database("server", "db", [Query="select * from dbo.FactSales"]),
  KeepColumns = Table.SelectColumns(Source, {"OrderDateTime", "ProductId", "Amount"}),
  Typed = Table.TransformColumnTypes(KeepColumns, {{"OrderDateTime", type datetime}}),
  Filtered = Table.SelectRows(Typed, each [OrderDateTime] >= RangeStart and [OrderDateTime] < RangeEnd),
  // cięższe kroki dopiero tutaj
  Added = Table.AddColumn(Filtered, "AmountPLN", each [Amount] * 1.0, type number)
in
  Added

Kluczowy element to nie sam filtr, ale to, że jest zastosowany przed krokami, które mogłyby wymusić przetworzenie całości.

7. Typowe błędy wdrożeniowe: co sprawia, że incremental refresh „mieli” dane

Incremental refresh działa dobrze tylko wtedy, gdy proces odświeżania potrafi jednoznacznie wybrać mały zakres danych do przeliczenia i przenieść ten wybór do źródła. W praktyce najczęstsze problemy nie wynikają z samej funkcji, lecz z tego, jak zaprojektowano zapytania, typy danych i model oraz jak zmienia się środowisko w czasie.

  • Transformacje wykonywane po filtrze daty (lub ukryte „psucie” selektywności)

    Klasyczny błąd to dodanie kroków, które zmieniają logikę filtrowania czasu już po tym, jak zastosowano ograniczenie do zakresu odświeżania. Nawet jeśli filtr daty istnieje, niektóre operacje potrafią sprawić, że silnik nie jest w stanie utrzymać selektywności i wraca do przetwarzania szerokiego zakresu danych. Objawem bywa nagły wzrost czasu odświeżania oraz liczby przetwarzanych rekordów mimo niezmienionych polityk.

    Ryzykowne są szczególnie transformacje, które zależą od całego zbioru (np. logika wymagająca „wiedzy” o danych spoza okna) albo zmieniają znaczenie kolumny czasu użytej do filtrowania, przez co granice partycji przestają odpowiadać temu, co rzeczywiście trafia do modelu.

  • Niepoprawne typy danych (Date vs DateTime, tekstowa data, niejawne konwersje)

    Incremental refresh opiera się na porównaniach wartości czasu. Gdy kolumna daty/czasu ma zły typ, jest tekstem lub bywa niejawnie rzutowana w trakcie transformacji, pojawiają się dwa skutki: po pierwsze filtr może działać inaczej niż oczekujesz (np. porównania leksykograficzne zamiast czasowych), a po drugie rośnie ryzyko, że mechanizm odświeżania nie będzie w stanie zastosować ograniczeń w sposób efektywny. Częstym symptometem są „dziury” w danych, duplikaty na granicach okien lub konieczność pełnego odświeżenia przy pozornie drobnej zmianie.

    Problematyczne są też niespójności w strefach czasowych i mieszanie wartości lokalnych z UTC, kiedy „ten sam” moment trafia do różnych partycji w zależności od sposobu interpretacji czasu.

  • Brak indeksów i niewydajne filtrowanie po stronie źródła

    Nawet idealnie zaprojektowane okno odświeżania nie pomoże, jeśli źródło nie potrafi szybko znaleźć wierszy z danego zakresu czasu. Gdy kolumna używana do ograniczenia zakresu nie ma indeksu (lub indeks nie jest używany), baza skanuje duże fragmenty tabeli, a odświeżanie „mieli” dane po stronie źródła zamiast pobierać wycinek.

    W praktyce objawia się to długimi czasami odpowiedzi, wzrostem obciążenia bazy oraz nieproporcjonalnie długim odświeżaniem nawet przy małym oknie zmian. Problem często jest mylony z „winą Power BI”, a faktycznie wynika z projektu i utrzymania warstwy źródłowej.

  • Niestabilne klucze i zmieniające się identyfikatory (duplikaty, „wędrówka” rekordów między partycjami)

    Incremental refresh zakłada przewidywalność: rekordy mają stabilne identyfikatory, a kolumna czasu ma jasne znaczenie (np. data transakcji vs data modyfikacji). Jeśli klucze biznesowe nie są stałe, system źródłowy „przepina” identyfikatory, albo rekordy są aktualizowane w sposób, który powoduje przesuwanie ich w czasie, pojawiają się trudne do wykrycia skutki: duplikaty, brakujące wiersze lub konieczność poszerzania okna zmian, co z kolei zwiększa zakres przetwarzania.

    Typowym problemem jest też wybór niewłaściwej kolumny czasu do partycjonowania: gdy partycje są budowane po dacie zdarzenia, a zmiany przychodzą według daty modyfikacji, to realne „delta changes” nie mieszczą się w odświeżanym oknie i zaczyna się kaskada poprawek.

  • Zmiany schematu: nowe kolumny, zmiana typów, zmiana nazewnictwa, ewolucja danych

    Incremental refresh jest wrażliwy na ewolucję schematu. Dodanie kolumny, zmiana typu lub semantyki istniejących pól może wymusić przebudowę danych historycznych albo spowodować niespójność między partycjami (np. różne typy w różnych okresach). W skrajnym przypadku prowadzi to do przerwania odświeżania lub do „cichego” przekształcania wartości, które zmienia wyniki analiz.

    Ryzyko rośnie, gdy transformacje opierają się na twardo zakodowanych nazwach kolumn, a źródło danych jest rozwijane iteracyjnie. Wtedy drobna zmiana po stronie systemu transakcyjnego potrafi uruchomić kosztowny scenariusz naprawczy, w którym trzeba odtworzyć partycje lub wykonać pełny refresh.

  • Niejednoznaczna definicja „okna zmian” i zbyt optymistyczne założenia o aktualizacjach

    Często zakłada się, że dane „stare” się nie zmieniają, podczas gdy korekty przychodzą z opóźnieniem lub są wykonywane masowo (np. rozliczenia, korekty księgowe, reimporty). Jeśli okno zmian jest zbyt wąskie, poprawki nie zostaną uchwycone i użytkownicy zobaczą niespójności. Jeśli okno zmian jest zbyt szerokie, incremental refresh zacznie w praktyce przeliczać dużą część historii i traci sens.

    To błąd wdrożeniowy, bo wynika z niedopasowania polityki odświeżania do realnego procesu biznesowego i technicznego sposobu dostarczania danych.

  • Błędy graniczne na styku partycji (off-by-one) i niespójne reguły inkluzywności

    Niewielkie różnice w tym, czy granice zakresu są traktowane jako „włącznie” czy „wyłącznie”, potrafią generować duplikaty lub luki dokładnie na przełomach dni/godzin. Takie problemy są trudne do wykrycia, bo dotyczą tylko niewielkiego procenta rekordów, ale uderzają w zaufanie do raportów. Najczęściej ujawniają się przy zmianie czasu, w danych z wielu stref czasowych lub przy łączeniu źródeł o różnych precyzjach (data vs data i czas).

Wdrożenia incremental refresh najczęściej wykolejają się nie przez brak samej funkcji, lecz przez połączenie kilku drobnych potknięć: niepewnego typu czasu, słabego wsparcia po stronie źródła, niestabilnych kluczy i zmian schematu. Jeśli widzisz, że odświeżanie rośnie wykładniczo, a zakres danych do pobrania „teoretycznie” jest mały, przyczyna zwykle leży w jednym z powyższych obszarów.

💡 Pro tip: Gdy incremental refresh „mieli”, najpierw sprawdź trzy rzeczy: czy folding działa, czy typ/strefa czasowa kolumny jest spójna z parametrami, oraz czy w źródle jest indeks/partycjonowanie po tej kolumnie. Potem zweryfikuj „off-by-one” na styku partycji i czy okno zmian odpowiada realnym korektom (late-arriving updates), bo to najczęściej generuje luki/duplikaty lub wymusza zbyt szerokie odświeżanie.

8. Checklist wdrożeniowy oraz najczęstsze symptomy i naprawy

Na etapie wdrożenia incremental refresh najwięcej czasu traci się nie na samym włączeniu funkcji, tylko na dopięciu szczegółów, które decydują o tym, czy odświeżanie będzie przewidywalne, szybkie i „nie przemieli” historii. Poniżej masz checklistę do przejścia przed publikacją oraz mapę objawów, które najczęściej wskazują na problem z parametrami, foldowaniem, partycjonowaniem albo oknem zmian.

Checklist wdrożeniowy (przed publikacją i po pierwszym odświeżeniu)

  • Weryfikacja scenariusza: czy dane faktycznie przyrastają w czasie i czy „stare” okresy nie zmieniają się masowo; jeśli nie, incremental refresh może nie dać korzyści albo utrudnić diagnostykę.
  • Jednoznaczna kolumna czasu: czy tabela faktów ma stabilną kolumnę daty/czasu, która jest logiczną osią partycjonowania (bez mieszania kilku definicji czasu w jednym filtrze).
  • Parametry zakresu: czy RangeStart/RangeEnd są w odpowiednim typie i zgodne z semantyką źródła (szczególnie przy UTC vs czas lokalny) oraz czy ich wartości testowe nie powodują „dziur” ani nakładania zakresów.
  • Filtr czasu możliwie wcześnie: czy warunek zakresu jest zastosowany na tyle wcześnie w zapytaniu, aby źródło mogło ograniczyć skan danych (to zwykle przesądza o tym, czy refresh będzie przyrostowy w praktyce).
  • Minimalizacja kroków ryzykownych: czy nie ma transformacji znanych z łamania optymalizacji (np. niepotrzebne sortowania, łączenia, wyliczenia na całej tabeli) wykonywanych przed ograniczeniem zakresu.
  • Spójność typów i stref czasowych: czy typ kolumny daty/czasu w modelu, w Power Query i w źródle jest spójny; czy świadomie zdecydowano o UTC/local i konsekwentnie tego przestrzegano.
  • Polityka odświeżania i retencji: czy okno przechowywania i okno zmian są zgodne z biznesem (np. korekty do 7 dni, ale dane trzymane 5 lat) oraz czy nie wymuszają częstego „dotykania” bardzo starych partycji.
  • Wydajność źródła: czy w źródle istnieją indeksy/partycje/klastry po kolumnie czasu oraz czy predykat czasu jest selektywny; brak tego często oznacza, że nawet poprawnie ustawiony incremental refresh będzie wolny.
  • Stabilne klucze i deduplikacja: czy klucze w faktach są stabilne, a ewentualne usuwanie duplikatów nie wymusza skanowania całej historii przy każdym odświeżeniu.
  • Test na małym oknie: czy wykonano testy na krótkim zakresie czasu (np. kilka dni) i potwierdzono, że odświeżanie rzeczywiście ogranicza się do oczekiwanych okresów.
  • Kontrola pierwszego pełnego odświeżenia: czy zaplanowano czas i zasoby na initial load (pierwsze odświeżenie i utworzenie partycji), a dopiero potem ocenę „docelowej” szybkości.
  • Monitoring po publikacji: czy jest plan obserwowania czasu odświeżeń i anomalii (skoki czasu, błędy w losowych dniach, zmiany wolumenu danych) oraz jasna ścieżka rollbacku zmian w zapytaniu.

Najczęstsze symptomy i szybkie naprawy

  • Objaw: każde odświeżenie trwa prawie tyle samo, niezależnie od tego, że „przyrost” jest mały.
    Najczęstsza przyczyna: brak realnego ograniczenia danych po stronie źródła (odświeżanie przyrostowe „na papierze”, ale źródło skanuje całość).
    Naprawa: upewnij się, że filtr czasu działa na kolumnie, która istnieje w źródle i jest wykorzystywana w predykacie; przestaw kolejność kroków tak, by ograniczenie czasu było możliwie wcześnie; ogranicz transformacje wykonywane przed filtrem.
  • Objaw: odświeżenie dotyka zbyt wielu okresów (np. miesiące/kwartały wstecz), mimo że okno zmian jest krótkie.
    Najczęstsza przyczyna: zbyt szerokie okno zmian lub parametry zakresu niezgodne z realną granularnością danych (np. czas vs data), ewentualnie korekty w źródle sięgają dalej niż zakładano.
    Naprawa: dopasuj okno zmian do faktycznego procesu korekt; doprecyzuj granularność (data vs datetime) i ujednolić typy; potwierdź z właścicielem danych, jak daleko wstecz pojawiają się aktualizacje.
  • Objaw: braki danych na granicach dni/miesięcy lub „podwójne” rekordy na styku okresów.
    Najczęstsza przyczyna: niespójne rozumienie inkluzywności/ekskluzywności zakresu, zaokrąglenia czasu, różne strefy czasowe między źródłem i modelem.
    Naprawa: ujednolić strefę czasową (najczęściej UTC end-to-end) oraz upewnić się, że logika zakresu nie tworzy luk ani nakładek; skontrolować konwersje typu i ewentualne obcinanie części czasowej.
  • Objaw: odświeżenie kończy się błędem typu danych (nie da się porównać daty i tekstu / datetime i date).
    Najczęstsza przyczyna: kolumna czasu w źródle jest tekstem lub ma mieszane formaty; parametry mają inny typ niż kolumna filtrowana.
    Naprawa: wymuś spójny typ w źródle lub na początku zapytania; upewnij się, że parametry i kolumna porównywana mają zgodny typ i tę samą semantykę (date vs datetime).
  • Objaw: incremental refresh działa w Desktop, ale po publikacji zachowuje się inaczej lub jest wolniejszy.
    Najczęstsza przyczyna: inne warunki wykonania w usłudze (bramka, limity zasobów, inna ścieżka do źródła, inna konfiguracja poświadczeń) lub inne wartości parametrów testowych niż produkcyjne.
    Naprawa: potwierdź, że poświadczenia i gateway wskazują to samo źródło i tę samą warstwę; zweryfikuj wartości parametrów oraz rzeczywisty wolumen danych w produkcji; monitoruj czasy odświeżeń po stronie usługi.
  • Objaw: losowe błędy w trakcie odświeżania (timeouty, przerwane połączenia), szczególnie przy większym wolumenie.
    Najczęstsza przyczyna: źródło nie wyrabia z zapytaniem, brak indeksów po czasie, zbyt szeroki zakres odświeżania, konkurencja obciążeń.
    Naprawa: zmniejsz zakres odświeżania i okno zmian, jeśli to możliwe; zadbaj o indeks/partycjonowanie w źródle; przesuń odświeżanie na okno mniejszego obciążenia; rozważ optymalizacje w warstwie przygotowania danych.
  • Objaw: refresh przebudowuje „prawie wszystko” po drobnej zmianie w Power Query.
    Najczęstsza przyczyna: zmiana w krokach, która wpływa na logikę filtrowania lub łamie optymalizację, przez co system traci możliwość użycia istniejących partycji w przewidywalny sposób.
    Naprawa: ogranicz zmiany w krokach przed filtrem czasu; wprowadzaj zmiany iteracyjnie i mierz efekt; unikaj transformacji wymagających globalnego przeliczenia całej tabeli faktów.
  • Objaw: wartości miar „skaczą” po odświeżeniu, mimo że zakres zmian powinien obejmować tylko ostatnie dni.
    Najczęstsza przyczyna: korekty w danych historycznych (backfill), niestabilne klucze, albo logika łączeń/deduplikacji zmienia wynik wstecz.
    Naprawa: potwierdź, czy proces źródłowy nie przepisuje historii; ustabilizuj klucze; jeśli korekty są naturalne, dopasuj okno zmian lub wprowadź mechanizm, który świadomie obejmuje odpowiednio długi okres.
  • Objaw: nagły wzrost czasu odświeżenia po zmianie schematu w źródle.
    Najczęstsza przyczyna: zmieniona kolumna czasu, zmiana typu, dodane kolumny o wysokim koszcie, zmiany w widokach, które wymuszają pełniejsze skany.
    Naprawa: ustal stabilny kontrakt schematu dla tabeli faktów; weryfikuj zmiany typu i nazewnictwa; w razie potrzeby ogranicz zakres pobieranych kolumn i przywróć predykat czasu do formy, którą źródło potrafi zoptymalizować.
  • Objaw: duży przyrost rozmiaru modelu mimo krótkiego okna retencji.
    Najczęstsza przyczyna: zbyt wysoka granularność czasu, zbędne kolumny tekstowe, albo brak kontroli nad tym, co faktycznie jest ładowane i kompresowane.
    Naprawa: ogranicz kolumny do niezbędnych, ustandaryzuj typy i słowniki; rozważ obniżenie granularności, jeśli biznesowo dopuszczalne; dopilnuj, by retencja odpowiadała temu, co realnie ma zostać w modelu.

Jeśli potraktujesz checklistę jako bramkę jakości (przed publikacją) i mapę diagnostyczną (po publikacji), incremental refresh przestaje być „magią”, a staje się przewidywalnym mechanizmem: odświeża to, co trzeba, kiedy trzeba, bez niepotrzebnego mielenia historii.

W Cognity łączymy teorię z praktyką – dlatego te zagadnienia rozwijamy także w formie ćwiczeń na szkoleniach.

icon

Formularz kontaktowyContact form

Imię *Name
NazwiskoSurname
Adres e-mail *E-mail address
Telefon *Phone number
UwagiComments