Direct Lake bez mitów: kiedy przyspiesza raporty, a kiedy daje gorsze SLA (checklista)

Praktyczny przewodnik po Direct Lake w Fabric/Power BI: jak działa, kiedy przyspiesza raporty, a kiedy psuje SLA. Symptomy, diagnostyka i checklista wyboru trybu.
16 maja 2026
blog

1. Czym jest tryb Direct Lake i gdzie pasuje w Fabric/Power BI

Direct Lake to tryb dostępu do danych w semantycznym modelu Power BI (w Microsoft Fabric), w którym raporty i zapytania mogą korzystać bezpośrednio z danych zapisanych w OneLake (najczęściej w formatach plikowych typu Delta/Parquet), bez klasycznego, pełnego importu danych do pamięci modelu w momencie odświeżenia.

W praktyce Direct Lake ma ambicję połączyć dwie potrzeby, które często się wykluczają: „chcę szybko jak w Import” oraz „chcę pracować na danych z jeziora jak w DirectQuery”. Nie jest to jednak „magiczny trzeci tryb” dobry zawsze — to konkretny kompromis, który w jednych układach środowiska i danych daje dużą przewagę, a w innych wprowadza nowe źródła opóźnień i ryzyk SLA.

Najprościej: Direct Lake jest naturalnym wyborem, gdy Twoje dane już żyją w Fabric i są utrzymywane w warstwie lakehouse/warehouse, a jednocześnie chcesz budować raporty Power BI na wspólnym, centralnym źródle danych, minimalizując duplikację i ciężar tradycyjnych odświeżeń importu.

Gdzie Direct Lake pasuje w ekosystemie Fabric/Power BI

  • Fabric jako platforma danych end-to-end: dane są ładowane, transformowane i przechowywane w OneLake, a Power BI „sięga” po nie w modelu semantycznym bez konieczności budowania osobnych kopii w każdym raporcie.
  • Jeden „punkt prawdy” dla wielu raportów: ten sam zestaw danych w lake może zasilać wiele modeli/raportów, sprzyjając spójności definicji miar i metryk.
  • Scenariusze, gdzie kluczowe jest skrócenie czasu od danych do raportu: gdy częste zmiany w danych lub w pipeline’ach mają być szybko widoczne w analityce, a pełny import i jego harmonogram stają się wąskim gardłem.
  • Środowiska z naciskiem na governance: centralne przechowywanie w OneLake ułatwia podejście „data platform first”, zamiast mnożenia lokalnych kopii danych w modelach importowanych.

Direct Lake a Import i DirectQuery — różnice w zastosowaniu (bez wchodzenia w mechanikę)

  • Import: dane są kopiowane do modelu (in-memory). Zwykle daje bardzo dobrą, przewidywalną interaktywność raportów, ale wymaga odświeżeń i utrzymywania kopii danych. Najlepszy, gdy dane zmieniają się rzadziej, a priorytetem jest stabilna wydajność.
  • DirectQuery: zapytania „lecą” do źródła (np. hurtowni) w czasie interakcji. Dobry przy dużej skali i potrzebie pracy na bieżących danych, ale wrażliwy na opóźnienia źródła, obciążenie i złożoność zapytań. Często trudniej osiągnąć powtarzalne czasy odpowiedzi.
  • Direct Lake: celuje w szybkie raportowanie na danych z jeziora, ograniczając klasyczną potrzebę importu. W wielu przypadkach może dać odczucie „prawie jak Import”, ale jego skuteczność zależy od tego, jak dane są zorganizowane i jak środowisko jest obciążone.

Kiedy warto rozważyć Direct Lake jako domyślny wybór

  • Gdy organizacja standardyzuje analitykę na Fabric i OneLake, a dane są utrzymywane w lakehouse/warehouse jako „system analityczny pierwszego wyboru”.
  • Gdy chcesz ograniczyć duplikację danych i koszty operacyjne związane z częstymi, ciężkimi odświeżeniami importu.
  • Gdy zależy Ci na szybkiej iteracji nad raportami i modelami, bez każdorazowego „przepalania” czasu na pełne przeładowania.

Co jest ważne na starcie (żeby nie budować oczekiwań „na skróty”)

Direct Lake nie zastępuje dobrego modelowania ani nie eliminuje ograniczeń wynikających z kształtu danych i obciążenia capacity. Traktuj go jako tryb zoptymalizowany pod Fabric i OneLake, który może znacząco poprawić czas odpowiedzi raportów w odpowiednich warunkach, ale wymaga świadomego dopasowania do scenariusza biznesowego, architektury danych i wymaganego SLA.

Jak działa Direct Lake (uproszczony mechanizm: OneLake, Delta/Parquet, semantyczny model, cache)

Direct Lake to tryb, w którym semantyczny model Power BI/Fabric odczytuje dane bezpośrednio z plików przechowywanych w OneLake (najczęściej w formacie Delta Lake, czyli pliki Parquet + transakcyjny log). W praktyce oznacza to, że raport nie musi czekać na klasyczny import całej tabeli do własnej kopii danych, a jednocześnie może korzystać z wielu korzyści znanych z modeli importowanych, gdy dane zostaną „rozgrzane” w pamięci.

Z doświadczenia szkoleniowego Cognity wiemy, że ten temat budzi duże zainteresowanie – również wśród osób zaawansowanych. Najważniejsze jest rozróżnienie trzech warstw: gdzie leżą dane, kto je interpretuje oraz jak przyspieszane są zapytania.

  • OneLake to wspólny magazyn plików w Fabric. To tutaj trafiają dane z lakehouse/warehouse i tu leżą pliki, które Direct Lake ma czytać.
  • Delta/Parquet to sposób zapisu danych w jeziorze. Parquet przechowuje kolumny wydajnie do analityki, a Delta dodaje warstwę „porządku” (metadane i historia zmian), dzięki czemu silnik wie, które pliki składają się na aktualny stan tabeli.
  • Semantyczny model to warstwa biznesowa w Power BI: miary, relacje, hierarchie, formatowania, RLS/OLS. W Direct Lake model nie „przechowuje” danych w klasycznym sensie importu, ale nadal jest miejscem, gdzie definiujesz logikę analityczną.
  • Cache to mechanizm przyspieszania: część danych (lub ich reprezentacji) może zostać załadowana do pamięci, aby kolejne zapytania nie musiały za każdym razem czytać tych samych fragmentów z plików.

Uproszczony przepływ wygląda tak:

  • Raport wysyła zapytanie do semantycznego modelu.
  • Silnik analizuje metadane tabel (Delta) i ustala, które pliki Parquet są potrzebne, aby odpowiedzieć na zapytanie.
  • Jeśli potrzebne fragmenty są już w cache, odpowiedź powstaje szybko na bazie pamięci. Jeśli nie, dane są doczytywane z OneLake i dopiero potem wykorzystywane do obliczeń.

Warto rozumieć, że Direct Lake nie jest po prostu „DirectQuery do plików”. W klasycznym DirectQuery zapytania są wykonywane na zewnętrznym silniku (np. w hurtowni SQL), co zwykle oznacza stałą zależność od wydajności źródła i sieci. W Direct Lake źródłem są pliki w OneLake, a mechanika wydajności opiera się na tym, jak efektywnie silnik potrafi wybrać właściwe pliki, odczytać tylko potrzebne kolumny/fragmenty oraz utrzymać używane dane w cache.

To prowadzi do dwóch kluczowych konsekwencji praktycznych:

  • Świeżość danych: ponieważ odczyt jest z warstwy plików, zmiany w tabelach lakehouse mogą być widoczne szybciej niż w podejściu opartym o pełne odświeżenia importu (choć nadal obowiązują reguły spójności metadanych i publikacji zmian w warstwie Delta).
  • Wydajność jest „warunkowa”: pierwsze zapytania mogą być wolniejsze (doczyt i wypełnianie cache), a kolejne – znacząco szybsze, jeśli trafiają w już ogrzane dane i korzystają z przewidywalnych wzorców zapytań.

Na tym etapie najważniejsze jest zapamiętanie, że Direct Lake to tryb łączący zalety świata jeziora danych (pliki w OneLake) z semantyką Power BI, a jego zachowanie w dużej mierze zależy od tego, czy i jak skutecznie działa cache oraz jak często zapytania zmuszają silnik do sięgania po nowe fragmenty danych w plikach.

3. Kiedy Direct Lake realnie przyspiesza raporty: typowe scenariusze i warunki brzegowe

Direct Lake potrafi dać bardzo szybkie czasy odpowiedzi, gdy trafia w właściwy profil danych i zapytań: raport korzysta z tabel w OneLake (Delta/Parquet), a silnik może efektywnie „podawać” dane do zapytań bez klasycznego, długiego importu i bez kosztów typowych dla trybu DirectQuery. W praktyce zyski pojawiają się wtedy, gdy zmienność danych, skala i wzorzec użycia raportu pasują do tego modelu.

Scenariusze, w których Direct Lake zwykle wygrywa

  • Duże modele, które muszą być „zawsze świeże” – gdy pełny import byłby długi lub częsty, a jednocześnie raporty mają intensywny ruch. Direct Lake redukuje narzut związany z klasycznymi cyklami ładowania danych do modelu.
  • Wiele raportów na wspólnym zestawie danych w OneLake – jeden „źródłowy” Lakehouse/Warehouse zasila wiele modeli/raportów; Direct Lake ogranicza duplikację danych i przyspiesza start pracy z nowym modelem (nie trzeba czekać na pełny import, by zacząć testy).
  • Interaktywne raporty z powtarzalnymi zapytaniami (te same przekroje, te same miary, podobne filtry) – zyski rosną, gdy użytkownicy wykonują dużo podobnych zapytań w krótkich odstępach czasu, bo „rozgrzany” model może szybko odpowiadać na kolejne interakcje.
  • Modele o rozsądnej granulacji i dobrze ułożonej gwieździe – typowe układy: jedna tabela faktów + kilka wymiarów, proste relacje, większość miar to standardowe agregacje. Im mniej „egzotyki” w modelowaniu, tym częściej zapytania układają się w efektywne plany.
  • Przewaga odczytów nad zapisami – gdy dane są aktualizowane porcjami (np. co 15–60 minut lub w kilku oknach dziennie), a w międzyczasie dominuje odczyt (dużo użytkowników/odświeżeń wizualizacji), Direct Lake zwykle daje bardzo dobry stosunek wydajności do operacyjnego narzutu.

„Warunki brzegowe” – kiedy przyspieszenie jest najbardziej prawdopodobne

Poniższe punkty nie są regułami absolutnymi, ale w praktyce mocno zwiększają szansę, że Direct Lake będzie odczuwalnie szybszy:

  • Dane w OneLake są uporządkowane pod analitykę: tabele w Delta/Parquet mają stabilny schemat, ograniczoną liczbę kolumn „tekstowych”, sensowne typy danych i unikają skrajnie wysokiej kardynalności tam, gdzie nie jest potrzebna.
  • Fakty mają naturalny wymiar czasu i da się je sensownie segmentować (np. po dacie) – nawet jeśli nie wchodzimy tu w techniki partycjonowania, sam fakt posiadania osi czasu i przewidywalnego dopływu danych pomaga utrzymać powtarzalny profil zapytań.
  • Zapytania są w dużej mierze agregacyjne: sumy, średnie, distinct count w rozsądnej skali, rankingi po agregatach; mniej jest zapytań „wypisujących” surowe rekordy na ekran.
  • Raport ma stały, przewidywalny ruch (wielu użytkowników w ciągu dnia), a nie wyłącznie sporadyczne wejścia raz na tydzień – wtedy „zimny start” ma mniejsze znaczenie, a korzyści z utrzymywania sprawnego stanu roboczego są większe.
  • Źródło prawdy jest jedno – unikasz sytuacji, w której ten sam fakt jest kopiowany i transformowany w kilku miejscach. Direct Lake najczęściej świeci wtedy, gdy model jest „blisko danych” i nie musi rekompensować chaosu w warstwie źródłowej.

Porównanie: kiedy Direct Lake daje największą przewagę nad Import i DirectQuery

Potrzeba / sytuacja Direct Lake – typowy efekt Dlaczego to zwykle działa
Duże wolumeny + częste aktualizacje Szybciej niż Import, stabilniej niż DirectQuery Mniej narzutu na cykl „załaduj całość”, brak typowego „obciążenia źródła” jak w DQ
Wiele raportów na tych samych tabelach w OneLake Szybsze uruchomienie i skalowanie rozwiązań Jeden wspólny zasób danych, mniej duplikacji i operacji przygotowawczych
Interaktywne dashboardy (wiele podobnych kliknięć) Krótsza latencja po „rozgrzaniu” Powtarzalność zapytań sprzyja szybkim odpowiedziom
Klasyczna gwiazda, proste miary Bardzo dobre czasy odpowiedzi Plan zapytania jest prostszy, a silnik łatwiej optymalizuje odczyty

Mini-checklista: „czy mam warunki na przyspieszenie?”

  • Czy dane są w OneLake w formacie Delta/Parquet i mają stabilny schemat?
  • Czy większość raportu to agregacje, a nie listowanie milionów wierszy?
  • Czy model jest możliwie „gwiazdowy” (fakty + wymiary), bez nadmiaru złożonych relacji?
  • Czy spodziewasz się regularnego ruchu użytkowników (a nie tylko sporadycznych wejść)?
  • Czy problemem jest czas i koszt częstych importów, a nie sama logika obliczeń w DAX?

Jeżeli na większość pytań odpowiadasz „tak”, Direct Lake bardzo często przynosi realne przyspieszenie odczu­walne w raportach: krótszy czas odpowiedzi na interakcje i mniejszy „operacyjny podatek” za utrzymywanie świeżości danych.

4. Kiedy Direct Lake może pogorszyć SLA: ryzyka, ograniczenia i antywzorce

Direct Lake potrafi być bardzo szybki, ale ma też scenariusze, w których łatwo o gorsze SLA niż w klasycznym Import (VertiPaq) albo nawet DirectQuery. Najczęściej dzieje się tak wtedy, gdy oczekujesz „importowej” przewidywalności, a w praktyce trafiasz na zimny start, presję na capacity, częste invalidacje cache lub ograniczenia funkcjonalne modelu. W czasie szkoleń Cognity ten temat bardzo często budzi ożywione dyskusje między uczestnikami, bo różnica między „szybko w demie” a „stabilnie w SLA” wychodzi dopiero przy realnym obciążeniu.

4.1. Ryzyka związane z cache i „zimnym startem”

  • Cold start po przerwie/skalowaniu/przeciążeniu – pierwsze otwarcie raportu lub pierwsze cięższe zapytania mogą mieć wyraźnie wyższą latencję, bo dane muszą zostać dociągnięte/utrwalone w warstwie przyspieszającej.
  • Częste wygaszanie efektu cache – jeśli dane w OneLake są aktualizowane w sposób, który stale zmienia wiele plików (np. „przepisywanie” dużych porcji danych), to korzyści z cache potrafią znikać, a użytkownicy częściej trafiają na wolniejsze wykonania.
  • Nieprzewidywalność piku użycia – w Import często „płacisz” koszt odświeżenia w oknie refresh, a odczyt jest stabilny; w Direct Lake część kosztu może pojawiać się w czasie interakcji użytkownika.

4.2. Presja na capacity i współdzielenie zasobów

  • Współdzielona pojemność (capacity) jako wąskie gardło – gdy wiele raportów/modeli konkuruje o te same zasoby, Direct Lake może zacząć „falować”: okresy bardzo szybkich odpowiedzi przeplatane spadkami.
  • Wysoka równoległość użytkowników – scenariusze z dużą liczbą jednoczesnych odpytań zwiększają ryzyko kolejek, time-outów i trudniejszej do utrzymania gwarancji czasu odpowiedzi.
  • Brak izolacji kosztu – jeśli w tej samej capacity dzieją się intensywne operacje (np. ETL/notebooks/inne obciążenia Fabric), to SLA raportowe może ucierpieć mimo poprawnego modelu.

4.3. Antywzorce w warstwie danych (Delta/Parquet w OneLake)

  • Zbyt małe pliki (small files problem) – duża liczba drobnych plików zwykle pogarsza czasy skanowania i narzut operacyjny, co może przełożyć się na wyższą latencję w raportach.
  • Niestabilny układ danych – częste reorganizacje, nadpisywanie partycji lub zmiany w strukturze plików potrafią zwiększać ryzyko „churnu” i utraty przewidywalności.
  • Brak sensownej strategii partycjonowania – jeśli dane nie wspierają naturalnych filtrów (np. po dacie) i typowych ścieżek zapytań, raporty częściej wykonują szerokie skany.
  • Mieszanie jakości danych i logiki – dokładanie ciężkich transformacji „na odczycie” zamiast stabilizacji w warstwie lakehouse/warehouse bywa przepisem na wahania SLA.

4.4. Antywzorce w modelu semantycznym i DAX (wysoki koszt zapytań)

  • Model „jak z Excela”: jedna wielka tabela – brak klasycznej gwiazdy (fakt + wymiary) często prowadzi do droższych zapytań i trudniejszej optymalizacji.
  • Relacje i filtracja sprzyjające eksplozji kombinacji – zbyt dużo dwukierunkowych relacji, nieintuicyjne ścieżki filtrowania, niekontrolowane many-to-many mogą zwiększać koszt obliczeń.
  • Miary o wysokiej złożoności – intensywne iteratory, zagnieżdżone IF-y i kosztowne wzorce w DAX potrafią zdominować czas odpowiedzi; Direct Lake nie „naprawi” drogiego DAX-u.
  • Zbyt dużo pól na wizualizacji – wysokie kardynalności na osiach/tabelach w połączeniu z miarami obliczeniowymi mogą powodować nagłe skoki latencji.

4.5. Ograniczenia funkcjonalne i „spadanie” do mniej korzystnego trybu

Ryzyko dla SLA rośnie, gdy rozwiązanie wymusza zachowania odbiegające od oczekiwanej ścieżki wykonania (np. przez niekompatybilne elementy modelu albo wymagania, które lepiej obsługuje Import). W praktyce oznacza to:

  • Niepełne dopasowanie funkcji – gdy potrzebujesz cech typowych dla klasycznego Import (np. bardzo przewidywalna interaktywność przy skomplikowanym modelu), Direct Lake może wymagać kompromisów.
  • „Niespodzianki” po zmianach – drobna modyfikacja danych lub modelu potrafi zmienić profil wykonywania zapytań i ujawnić wąskie gardła, których wcześniej nie było widać.
  • Oczekiwanie, że Direct Lake zastąpi wszystkie tryby – są przypadki, gdzie Import lub agregacje są po prostu stabilniejszym wyborem pod SLA.

4.6. Checklista: sygnały ostrzegawcze, że SLA może się pogorszyć

Obszar Sygnał Dlaczego to ryzyko dla SLA
Cache Użytkownicy skarżą się na wolne „pierwsze wejście” Cold start i brak rozgrzania cache pod typowe zapytania
OneLake pliki Bardzo dużo małych plików / częste nadpisywanie Większy narzut skanowania i częstsza utrata korzyści z cache
Capacity Wahania czasu odpowiedzi w ciągu dnia Konkurencja o zasoby i kolejki
Model Brak gwiazdy, dużo M2M, dwukierunkowe relacje Droższe zapytania, trudniejsza optymalizacja i większa zmienność czasów
DAX/wizualizacje Wysoka kardynalność + ciężkie miary na wielu wizualach Duża liczba wywołań i koszt obliczeń dominuje nad odczytem danych

Praktyczna zasada: jeśli Twoje SLA wymaga stałej, niskiej latencji przy dużej równoległości i częstych zmianach danych, Direct Lake trzeba traktować jako tryb, który wymaga dyscypliny w warstwie danych, modelu i zarządzaniu capacity — inaczej zamiast przyspieszenia dostaniesz większą zmienność czasów odpowiedzi.

5. Typowe symptomy problemów: latencja, cold start, przeciążenie capacity, opóźnienia odświeżeń

Direct Lake potrafi być bardzo szybki, ale gdy coś „nie gra”, objawy zwykle układają się w kilka powtarzalnych wzorców. Poniżej znajdziesz checklistę symptomów, które najczęściej widać z perspektywy użytkownika raportu i właściciela capacity — zanim jeszcze wejdziesz w szczegółową diagnostykę.

5.1. Latencja w raporcie: „czasem szybko, czasem dramat”

Najbardziej mylący symptom to niestabilny czas odpowiedzi: te same wizualizacje potrafią działać raz płynnie, a innym razem „mielą” kilkanaście–kilkadziesiąt sekund. W Direct Lake to często oznacza, że część zapytań nie korzysta z oczekiwanego toru wykonania (np. cache), albo środowisko jest w danym momencie pod presją zasobów.

  • Długi czas otwierania strony raportu mimo niewielkiej liczby wizualizacji.
  • Skoki czasu odpowiedzi po kliknięciu filtra/segmentatora (czasem 1–2 s, czasem 20+ s).
  • Różne czasy dla różnych użytkowników w tym samym czasie (często koreluje z obciążeniem capacity lub „rozgrzaniem” cache).
  • Wizualizacje z opóźnionym dorysowaniem: część elementów ładuje się szybko, a pojedyncze wykresy blokują całą stronę.

W praktyce: jeżeli użytkownicy mówią „raport jest losowy”, to zwykle problemem nie jest pojedyncza miara DAX, tylko zmienność ścieżki wykonania lub zasobów.

5.2. Cold start: „pierwszy użytkownik cierpi najbardziej”

Cold start to sytuacja, w której pierwsze zapytania po okresie bezczynności są wyraźnie wolniejsze niż kolejne. W Direct Lake bywa to naturalne, ale w niektórych modelach potrafi zdominować odczucie SLA.

  • Pierwsze wejście rano (lub po przerwie) ładuje się długo, potem jest „już dobrze”.
  • Odświeżenie karty przeglądarki po dłuższej przerwie powoduje wyraźny regres czasu.
  • Testy deweloperskie są mylące: drugi i trzeci przebieg weryfikacji wydajności wypada znacznie lepiej niż „prawdziwe pierwsze wejście”.

W praktyce: cold start jest szczególnie bolesny, gdy raport jest używany rzadko, ale ma „ostre” oczekiwania czasowe (np. poranne odprawy, operacje w oknie czasowym).

5.3. Przeciążenie capacity: „wszystko zwalnia naraz”

Gdy capacity jest przeciążone, objawy nie ograniczają się do jednego raportu. Użytkownicy widzą problemy „systemowo”, a nie tylko w konkretnym dashboardzie.

  • Wspólny spadek wydajności wielu raportów i workspace’ów na tej samej capacity.
  • Wydłużone czasy odświeżeń i interakcji w raportach w tych samych godzinach (np. „zawsze koło 10:00”).
  • Kolejkowanie/oczekiwanie: użytkownik ma wrażenie „ciszy”, a potem nagle wszystko wskakuje.
  • Losowe błędy lub time-outy przy cięższych stronach raportu (szczególnie przy dużej liczbie jednoczesnych użytkowników).

W praktyce: jeśli problem narasta wraz z liczbą osób na raporcie, to częściej jest to symptom capacity niż „złego DAX-a”.

5.4. Opóźnienia „odświeżeń” i efekt: dane nie są tak świeże, jak obiecano

Direct Lake nie eliminuje całkowicie pojęcia opóźnień między zmianą danych a tym, co widzi raport. Typowe symptomy to rozjazd między tym, co jest w źródłowych plikach/warstwie danych, a tym, co serwuje model semantyczny.

  • Użytkownik widzi „stare” wartości mimo że upstream (pipeline/lakehouse/warehouse) już dostarczył nową porcję.
  • „Dane znikają i wracają” w krótkich oknach czasu (np. w trakcie ładowań/commitów) — raport raz pokazuje wynik A, raz B.
  • Opóźnienia po dużych wsadach: po większym ładunku dane pojawiają się w raporcie później niż zwykle.
  • Nieprzewidywalność w oknie ETL/ELT: w trakcie ładowań raport potrafi reagować gorzej lub pokazywać niespójne przekroje.

W praktyce: dla SLA ważne jest rozróżnienie „czas dostarczenia danych do lake” vs „czas, kiedy raport konsekwentnie je widzi”.

5.5. Szybka checklista: symptom → najczęstszy kierunek hipotezy

Symptom Jak to wygląda dla użytkownika Najczęstszy kierunek hipotezy
Wysoka latencja tylko czasami „Raz 2 sekundy, raz 25” Brak stabilnego wykorzystania cache / zmienna ścieżka wykonania / konkurencja o zasoby
Cold start „Pierwsze wejście boli, potem ok” „Rozgrzewanie” modelu i cache; bezczynność lub rzadkie użycie
Spowolnienie wielu raportów jednocześnie „Dziś wszystko wolne” Przeciążenie capacity / równoległe obciążenia (interaktywne + batch)
Time-outy na cięższych stronach „Nie doczytuje, kręci się w nieskończoność” Za ciężkie zapytania w stosunku do zasobów; skoki obciążenia; limity czasu
„Dane nieaktualne” mimo zakończonych ładowań „W źródle jest, w raporcie nie ma” Opóźnienie widoczności zmian dla modelu/raportu; okna przetwarzania i spójności

5.6. Minimalne testy obserwacyjne (bez narzędzi)

Jeśli chcesz szybko sklasyfikować problem, zanim wejdziesz w telemetry i metryki:

  • Porównaj pierwszy i drugi przebieg tej samej interakcji (np. filtr regionu): duża różnica sugeruje cold start/cache.
  • Sprawdź „godziny szczytu”: jeśli problem występuje falami o stałych porach, to silny trop w stronę capacity i równoległych obciążeń.
  • Porównaj różne strony raportu: jeśli tylko jedna strona jest problematyczna, to częściej wzorzec zapytań/modelu; jeśli wszystkie — bardziej systemowo.
  • Zweryfikuj świeżość na prostym liczniku (np. miara „Max(DataAktualizacji)”): pomaga odróżnić problem wydajności od problemu dostępności/aktualności danych.

6. Diagnostyka krok po kroku: co mierzyć i gdzie szukać

W Direct Lake najczęściej nie chodzi o „czy działa”, tylko dlaczego raz działa szybko, a raz wolno. Poniżej masz praktyczną procedurę: od objawu w raporcie, przez metryki zapytań, po obciążenie capacity i sygnały z logów. Celem jest rozdzielenie problemów na: warstwa wizualizacji, warstwa zapytań (DAX), warstwa odczytu danych/cache oraz resource/capacity.

Krok 0: Zdefiniuj cel diagnostyki (metryki, SLA, powtarzalność)

  • Ustal metryki: czas renderu wizualizacji, czas zapytania DAX, liczba zapytań na interakcję, P95/P99 latencji, odsetek cold start.
  • Ustal punkt odniesienia: ten sam raport, ten sam filtr, ta sama strona, podobna pora dnia (obciążenie capacity ma znaczenie).
  • Testuj w kontrolowanych warunkach: prywatne okno przeglądarki, bez cache przeglądarki, a potem powtórz z „rozgrzanym” raportem.

Krok 1: Performance Analyzer w Power BI – rozdziel „render” od „query”

Performance Analyzer pozwala szybko sprawdzić, czy winne jest DAX/źródło danych, czy raczej sama wizualizacja (render, układ, niestandardowe elementy).

  • Włącz Performance Analyzer i zbierz czasy dla: DAX query, Visual display, Other.
  • Eksportuj zapytania i czasy – to Twoja baza do porównań (przed/po zmianach, cold/warm).
  • Jeśli DAX query jest krótki, a całość wolna: szukaj kosztu po stronie wizualu (zbyt dużo punktów, złożone formatowanie, zbyt wiele elementów na stronie).
  • Jeśli DAX query dominuje: przejdź do narzędzi DAX/VertiPaq i capacity/logów.

Krok 2: Narzędzia DAX/VertiPaq – sprawdź, co naprawdę kosztuje

Gdy problemem jest czas zapytań, potrzebujesz wglądu w plan, storage engine i wzorce skanowania danych. To pozwala odróżnić: „źle napisany DAX” od „zbyt dużo danych do przeskanowania” oraz od „brak efektu cache”.

  • DAX Studio: uruchamiaj zapytania z Performance Analyzer i mierz m.in. czasy Server Timings (podział na Formula Engine vs Storage Engine) oraz liczbę zapytań.
  • VertiPaq Analyzer (np. jako część workflow z DAX Studio/Tabular Editor): sprawdź rozmiary kolumn, kardynalność, kompresję i potencjalne „ciężkie” kolumny, które podbijają skany.
  • Tabular Editor: szybki przegląd miar i zależności (które miary są używane przez wizualizacje) – ułatwia namierzenie kosztownych definicji.
Co obserwujeszNajbardziej pasujące narzędziePo co
Wolne konkretne wizualizacjePerformance AnalyzerOddzielić render od DAX i wskazać „winne” elementy
Wolne DAX, niejasna przyczynaDAX Studio (Server Timings)Rozróżnić Formula Engine vs Storage Engine
Skany dużych tabel/kolumnVertiPaq AnalyzerWskazać kosztowne kolumny i charakter modelu
Trudna nawigacja po logice modeluTabular EditorSzybko znaleźć zależności, miary i potencjalne „hot spots”

Krok 3: Fabric Capacity Metrics – czy problemem jest „brak mocy” i kolejki

Direct Lake jest wrażliwy na to, co dzieje się w capacity: przeciążenie, równoległość, kolejki i throttling potrafią wyglądać jak „losowa” degradacja czasu odpowiedzi.

  • Otwórz Fabric Capacity Metrics dla capacity, na którym działa raport/model.
  • Sprawdź piki obciążenia skorelowane czasowo z Twoimi testami (szczególnie w godzinach szczytu).
  • Wypatruj sygnałów typu: queueing (czekanie na zasoby), throttling, wysokie wykorzystanie CPU/Memory oraz nagłe wzrosty równoległych zapytań.
  • Porównaj: czas odpowiedzi dla tego samego scenariusza przy niskim vs wysokim obciążeniu – to najszybszy test, czy SLA „pływa” przez capacity.

Krok 4: Log Analytics / diagnostyczne logi – korelacja zdarzeń i przyczyn

Gdy Performance Analyzer i narzędzia DAX pokazują „że jest wolno”, logi pomagają odpowiedzieć dlaczego: czy były restarty, cache miss, problemy z dostępem do plików, błędy, czy zdarzenia po stronie capacity.

  • Włącz zbieranie danych diagnostycznych do Log Analytics dla odpowiednich zasobów/obszarów (Power BI/Fabric), aby mieć ciągłość i możliwość korelacji czasowej.
  • Koreluj po znacznikach czasu: interakcja w raporcie → zapytania → zdarzenia capacity → ewentualne błędy/ostrzeżenia.
  • Filtruj pod kątem: wzrostu latencji, wzrostu liczby zapytań, błędów czasowych, restartów/odświeżeń, anomalii w przepływie.

Krok 5: Szybka checklista „cold vs warm” (cache i start)

W Direct Lake duża część „magii” (i problemów) wygląda jak różnica między pierwszym a kolejnym uruchomieniem tego samego scenariusza. Nie musisz od razu wchodzić w szczegóły mechaniki cache, ale warto to zmierzyć.

  • Zmierz czas pierwszego wejścia na stronę raportu i czas tego samego wejścia po chwili (bez zmian filtrów).
  • Jeśli pierwsze odpalenie jest znacząco wolniejsze, a kolejne szybkie: problem często dotyczy „rozgrzewki” (cache, inicjalizacja, konkurencja o zasoby).
  • Jeśli zawsze jest wolno: bardziej prawdopodobny jest koszt zapytań/modelu lub permanentne przeciążenie capacity.

Krok 6: Minimalny zestaw testów izolujących (bez przebudowy modelu)

  • Test pojedynczej wizualizacji: skopiuj stronę i zostaw 1 wizual – sprawdzisz, czy problem to suma wielu zapytań naraz.
  • Test „bez filtrów” vs „z filtrami”: jeśli filtry dramatycznie pogarszają czas, podejrzewaj wysoką kardynalność/ciężkie relacje lub miary wrażliwe na kontekst.
  • Test w różnych porach: jeżeli P95 rośnie w godzinach szczytu, to mocny sygnał, że kluczowe są kolejki i obciążenie capacity.
  • Test powtarzalności: 10 powtórzeń tego samego scenariusza i zapis wyników – wahania są ważniejszą informacją niż średnia.

Krok 7: Co zapisać jako „pakiet diagnostyczny” (żeby nie wracać do tematu)

  • Z Performance Analyzer: czasy dla każdej wizualizacji + wyeksportowane zapytania.
  • Z DAX Studio: wyniki Server Timings (FE/SE) dla kluczowych zapytań.
  • Z Capacity Metrics: zrzut/wycinek czasowy obciążenia w trakcie testów.
  • Z logów: okno czasowe z eventami skorelowanymi z testem (błędy, throttling, kolejki).
  • Opis scenariusza testowego: filtry, użytkownik/rola, przeglądarka, godzina, czy cold/warm.

Najważniejsze: zaczynaj od Performance Analyzer (co jest wolne), przejdź do DAX/VertiPaq (dlaczego zapytanie jest drogie), a potem potwierdź w Capacity Metrics i logach (czy to problem zasobów i kolejek). Taka kolejność minimalizuje zgadywanie i pozwala szybko zawęzić przyczynę.

💡 Pro tip: Zacznij od Performance Analyzer i rozdziel, czy czas „ucieka” w DAX query czy w renderowaniu wizualu, a dopiero potem schodź niżej do DAX Studio/VertiPaq oraz Capacity Metrics i logów, żeby potwierdzić przyczynę. Każdy test rób powtarzalnie (ten sam scenariusz, cold vs warm, 10 powtórzeń) i zapisuj wyniki jako pakiet diagnostyczny, żeby nie wracać do punktu wyjścia.

7. Jak stabilizować wydajność: praktyczne techniki

Direct Lake potrafi dać świetne czasy odpowiedzi, ale bywa wrażliwy na „szczyty” obciążenia, zimny start oraz zmienność zapytań. Stabilizacja wydajności polega na ograniczeniu nieprzewidywalności: uproszczeniu ścieżki zapytania, kontrolowaniu rozmiaru skanów, utrzymaniu zdrowego cache i zapewnieniu wystarczających zasobów capacity.

7.1 Modelowanie: mniej pracy dla silnika, mniej ryzyka dla SLA

  • Trzymaj się schematu gwiazdy: fakt + wymiary, z jednoznacznymi relacjami i ograniczoną liczbą ścieżek filtrów. Złożone, „pajęczynowe” relacje częściej generują kosztowne plany zapytań i większą zmienność czasu odpowiedzi.
  • Ogranicz kardynalność: wysokokardynalne kolumny w faktach, niepotrzebne identyfikatory i pola tekstowe zwiększają koszt skanów i utrudniają cache’owanie wyników. Jeśli pole nie jest używane w raportach, nie wciągaj go do modelu.
  • Układaj miary pod typowe pytania biznesowe: miary, które wymuszają szerokie skany (np. przez skomplikowane warunki) częściej powodują piki latencji. Preferuj miary, które pracują na dobrze filtrowalnych wymiarach i przewidywalnych granicach czasu.
  • Porządkuj kierunki filtrowania: unikaj obustronnego filtrowania, jeśli nie jest konieczne. Zwiększa ono liczbę potencjalnych ścieżek i ryzyko kosztownych przeliczeń.
  • Dbaj o „higienę” wizualizacji: zbyt wiele elementów na stronie i nadmiar interakcji potrafią multiplikować liczbę zapytań. Stabilność często rośnie szybciej po uproszczeniu strony niż po „tuningu” pojedynczej miary.

7.2 Partycje i układ danych: kontroluj rozmiar skanów

  • Partycjonuj po czasie tam, gdzie to naturalne: zapytania raportowe zwykle i tak filtrują po okresach. Dobrze dobrane partycje ograniczają ilość danych czytanych przy typowych filtrach.
  • Utrzymuj spójny klucz partycjonowania z najczęstszymi filtrami w raportach (np. miesiąc, tydzień). Jeśli użytkownicy filtrują po dacie, a partycje są po innym atrybucie, zyski będą niewielkie.
  • Unikaj zbyt drobnych partycji: ich nadmiar zwiększa koszty zarządzania i może pogorszyć stabilność przy dużej liczbie równoległych zapytań.
  • Minimalizuj „przypadkowe” odczyty: jeśli dane są stale dopisywane, zaplanuj procesy tak, by nie wymuszały częstych, szerokich zmian w historycznych partycjach.

7.3 Agregacje: stała szybkość dla popularnych widoków

  • Wprowadź agregacje dla najczęstszych przekrojów: jeśli większość użytkowników analizuje dane na poziomie miesiąc/produkt/region, przygotuj warstwę agregacji, która te zapytania obsłuży przewidywalnie i szybko.
  • Mierz efekt biznesowy: agregacje mają sens, gdy redukują koszt typowych zapytań w godzinach szczytu. Jeśli każdy użytkownik drąży inne szczegóły, stabilność może bardziej poprawić uproszczenie modelu niż budowa wielu agregacji.
  • Ustal priorytety: lepiej jedna dobrze dobrana agregacja dla 70% ruchu niż wiele, które rzadko się aktywują.

7.4 Cache i „warm-up”: redukcja zimnego startu

  • Planuj rozgrzewanie krytycznych raportów: po wdrożeniu, zmianach w modelu lub okresach bezczynności pierwsze zapytania mogą być wolniejsze. Uruchomienie kontrolowanych, reprezentatywnych zapytań przed godzinami szczytu pomaga ustabilizować doświadczenie użytkowników.
  • Ogranicz częste zmiany, które unieważniają cache: jeśli pipeline’y danych lub model są przebudowywane zbyt często, system częściej wraca do trybu „cold”. Stabilność rośnie, gdy cykle publikacji i odświeżeń są przewidywalne.
  • Standaryzuj filtry startowe: raporty otwierające się na „całej historii” powodują większe skany i większą zmienność. Rozsądne domyślne filtry (np. ostatnie 12 miesięcy) pomagają zarówno wydajności, jak i cache’owaniu.

7.5 Zarządzanie capacity: SLA rodzi się w planowaniu zasobów

  • Oddziel obciążenia, jeśli to możliwe: interaktywne raportowanie i ciężkie procesy danych konkurują o te same zasoby. Stabilność SLA rośnie, gdy „noisy neighbor” jest minimalizowany poprzez separację lub harmonogramy.
  • Ustal okna dla zadań ciężkich: odświeżenia, przebudowy i większe operacje planuj poza godzinami największego ruchu użytkowników.
  • Kontroluj równoległość: wiele jednoczesnych zapytań do szerokich tabel potrafi wywołać kaskadowe spowolnienia. Czasem lepszy jest mniejszy throughput, ale bardziej przewidywalny czas odpowiedzi.
  • Reaguj na wzrost: jeśli stabilność spada przy określonym progu użytkowników lub danych, to sygnał do dostrojenia modelu albo skalowania zasobów. SLA nie „naprawia się” samo, gdy rośnie ruch.
  • Utrzymuj porządek w artefaktach: nieużywane modele, duplikaty raportów i eksperymentalne wersje potrafią generować nieoczekiwany ruch i zajmować zasoby, co obniża przewidywalność.

7.6 Checklista stabilizacji: szybkie decyzje przed wdrożeniem

  • Model: schemat gwiazdy, ograniczona kardynalność, brak zbędnych kolumn, proste relacje.
  • Dane: rozsądne partycje zgodne z filtrami użytkowników, minimalne zmiany w historii.
  • Zapytania: typowe ścieżki są szybkie i powtarzalne; raport nie startuje od „wszystkiego”.
  • Agregacje: istnieją dla najpopularniejszych przekrojów i rzeczywiście redukują koszt zapytań.
  • Cache: zaplanowany warm-up i przewidywalny rytm publikacji/odświeżeń.
  • Capacity: zaplanowane okna prac ciężkich, ograniczenie konkurencji obciążeń, gotowość do skalowania.

Jeśli potraktujesz Direct Lake jako element większego systemu (model + układ danych + zachowanie użytkowników + capacity), uzyskasz nie tylko szybkie czasy odpowiedzi, ale przede wszystkim powtarzalne czasy odpowiedzi — a to zwykle jest klucz do dobrego SLA.

💡 Pro tip: Stabilność w Direct Lake najczęściej wygrywa się prostotą i przewidywalnością: schemat gwiazdy, ograniczona kardynalność, sensowne partycje pod typowe filtry oraz „higiena” strony raportu, żeby nie mnożyć zapytań. Dodatkowo zaplanuj warm-up krytycznych raportów i zarządzaj capacity (okna na ciężkie prace, separacja obciążeń, gotowość do skalowania), bo to tam zwykle rodzą się wahania SLA.

8. Checklist „tak/nie”: jak wybrać Direct Lake vs Import vs DirectQuery

Odpowiedz „tak/nie” na pytania poniżej. Tam, gdzie pojawia się rekomendacja, traktuj ją jako domyślny wybór przy spełnionych warunkach.

  • Czy dane są w OneLake jako Lakehouse/Warehouse (Delta/Parquet) i mają być analizowane bez kopiowania do osobnego magazynu? Jeśli tak → rozważ Direct Lake. Jeśli nie → częściej Import lub DirectQuery (zależnie od źródła i wymagań świeżości).
  • Czy priorytetem jest najniższa latencja interakcji (slicery, drill, wiele wizualizacji na stronie) przy stabilnym SLA? Jeśli tak → najczęściej Import. Jeśli nie i akceptujesz pewną zmienność startu/rozgrzewania → Direct Lake bywa dobrym kompromisem.
  • Czy potrzebujesz bardzo częstych aktualizacji danych (prawie w czasie rzeczywistym) bez klasycznych okien odświeżania? Jeśli tak → częściej DirectQuery (albo architektura hybrydowa). Jeśli nieImport lub Direct Lake.
  • Czy użytkownicy oczekują w pełni przewidywalnego czasu odpowiedzi o każdej porze dnia (mała tolerancja na „cold start”)? Jeśli tak → preferuj Import. Jeśli nieDirect Lake może być akceptowalny.
  • Czy model ma być „self-service” i często zmieniają się miary, relacje, kolumny, logika biznesowa? Jeśli tak → zwykle najłatwiej utrzymać Import. Jeśli nie (model bardziej „produktowy”, kontrolowany) → Direct Lake lub DirectQuery zależnie od źródła.
  • Czy możesz pozwolić sobie na replikację danych (kopię) w modelu semantycznym i czas potrzebny na odświeżenia? Jeśli takImport. Jeśli nie (koszt/duplikacja/okna odświeżeń są problemem) → Direct Lake lub DirectQuery.
  • Czy raporty mają dużo użytkowników i wysoki współczynnik współbieżności, a capacity bywa wąskim gardłem? Jeśli tak → wybierz rozwiązanie o najbardziej stabilnym profilu obciążenia: zwykle Import; DirectQuery rozważ tylko, jeśli backend źródła to wytrzyma i jest odpowiednio skalowany. Jeśli nieDirect Lake jest częstym wyborem.
  • Czy Twoje źródło danych jest zoptymalizowane pod zapytania analityczne i ma przewidywalne czasy odpowiedzi (indeksy/statystyki/skala)? Jeśli takDirectQuery może mieć sens. Jeśli nie → unikaj DirectQuery; wybierz Import lub Direct Lake.
  • Czy potrzebujesz maksymalnej kontroli nad wydajnością przez projekt modelu (agregacje, prekomputacje, zoptymalizowany układ danych) bez zależności od kondycji źródła? Jeśli takImport. Jeśli nieDirect Lake lub DirectQuery.
  • Czy dane są bardzo duże i rosną szybko, a pełne odświeżenia importu są niepraktyczne organizacyjnie? Jeśli tak → rozważ Direct Lake (gdy dane są w OneLake) albo DirectQuery (gdy źródło jest poza OneLake i ma mocny silnik). Jeśli nieImport.
  • Czy dopuszczasz, że przy skokach obciążenia część zapytań będzie „bardziej zmienna” (czasem szybciej, czasem wolniej) i chcesz minimalizować operacje odświeżania? Jeśli takDirect Lake. Jeśli nieImport (lub dobrze zaprojektowany DirectQuery na mocnym backendzie).
  • Czy masz twarde wymagania co do ograniczeń funkcjonalnych trybu (np. to, co jest dostępne/ograniczone w danym trybie łączności)? Jeśli tak → wybierz tryb, który spełnia wymagania bez obejść (najczęściej Import). Jeśli nie → kieruj się wydajnością i SLA: Import dla stabilności, Direct Lake dla pracy „na lake” bez kopiowania, DirectQuery dla świeżości zależnej od źródła.

Szybka interpretacja wyników: jeśli na większość pytań o stabilne SLA i najniższą latencję odpowiadasz „tak” → Import. Jeśli dominują odpowiedzi „tak” przy danych w OneLake i chęci uniknięcia kopii/odświeżeńDirect Lake. Jeśli dominują „tak” przy świeżości w czasie bliskim rzeczywistemu i masz mocne, skalowalne źródło → DirectQuery.

Jeśli chcesz poznać więcej takich przykładów, zapraszamy na szkolenia Cognity, gdzie rozwijamy ten temat w praktyce.

Majczęściej zadawane pytania i odpowiedzi odnośnie Direct Lake bez mitów: kiedy przyspiesza raporty, a kiedy daje gorsze SLA (checklista)

Kiedy Direct Lake jest lepszym wyborem niż klasyczny Import w Power BI?

Direct Lake jest lepszym wyborem wtedy, gdy dane już są w OneLake i chcesz ograniczyć kopiowanie oraz ciężkie odświeżenia importu. Najwięcej zyskujesz przy dużych wolumenach, częstszych zmianach danych i wielu raportach korzystających ze wspólnego źródła. Jeśli jednak priorytetem jest maksymalnie przewidywalna, stała latencja interakcji, klasyczny Import nadal często wygrywa pod kątem SLA.

Czy Direct Lake działa tak samo szybko jak Import?

Direct Lake nie działa zawsze tak samo szybko jak Import. W dobrych warunkach może dawać odczucie wydajności zbliżonej do Import, szczególnie po rozgrzaniu cache i przy powtarzalnych zapytaniach. Różnica polega na tym, że Direct Lake jest bardziej wrażliwy na zimny start, układ danych w OneLake, obciążenie capacity oraz koszt samych zapytań i modelu.

Jakie raporty i modele najczęściej zyskują na Direct Lake?

Najczęściej zyskują raporty o przewidywalnych, agregacyjnych zapytaniach i modele zbudowane w układzie gwiazdy. Direct Lake dobrze sprawdza się tam, gdzie użytkownicy często analizują te same przekroje danych, a raport nie próbuje wyświetlać ogromnych wolumenów surowych rekordów. Szczególnie sprzyjające są takie warunki:

  • jedna tabela faktów i kilka wymiarów,
  • proste relacje i standardowe miary,
  • regularny ruch użytkowników w ciągu dnia.
Dlaczego Direct Lake może pogorszyć SLA mimo że ma przyspieszać raporty?

Direct Lake może pogorszyć SLA, gdy koszt wydajności pojawia się w czasie interakcji użytkownika, a nie wcześniej podczas odświeżenia. Problem zwykle wynika z cold startu, presji na capacity, częstych zmian w plikach OneLake albo zbyt ciężkiego modelu i DAX. Wtedy raport bywa szybki tylko czasami, a nie w sposób stabilny i przewidywalny.

Po czym poznać, że problem w Direct Lake wynika z cache albo cold startu?

Najczęstszy sygnał to wyraźnie wolniejsze pierwsze wejście niż kolejne uruchomienia tego samego raportu. Jeśli ta sama strona rano ładuje się długo, a chwilę później działa już sprawnie, podejrzenie pada na rozgrzewanie cache. Pomocne są proste obserwacje:

  • porównanie pierwszego i drugiego otwarcia tej samej strony,
  • sprawdzenie, czy problem znika po kilku podobnych kliknięciach,
  • ocena, czy spowolnienie dotyczy głównie raportów używanych sporadycznie.
Jakie błędy w modelu danych najczęściej psują wydajność Direct Lake?

Najczęściej wydajność psuje model bez schematu gwiazdy, z nadmiarem relacji i kosztownymi miarami DAX. Direct Lake nie naprawia słabego modelowania. Ryzykowne są szczególnie jedna wielka tabela, relacje many-to-many, dwukierunkowe filtrowanie oraz wysokokardynalne pola na wizualizacjach. Gdy do tego dochodzą ciężkie iteratory i złożone warunki w DAX, latencja szybko przestaje być przewidywalna.

Od czego zacząć diagnostykę, gdy raport Direct Lake działa nierówno?

Najlepiej zacząć od rozdzielenia problemu na zapytanie, render wizualizacji i zasoby capacity. Pierwszym krokiem powinien być Performance Analyzer, bo pokazuje, czy czas ucieka w DAX query czy w samo wyświetlanie wizualu. Dopiero potem warto przejść do DAX Studio, analizy modelu oraz Fabric Capacity Metrics, aby potwierdzić, czy źródłem problemu jest logika zapytania czy przeciążenie środowiska.

Jak w praktyce ograniczyć ryzyko słabego SLA przy wdrożeniu Direct Lake?

Ryzyko słabego SLA ogranicza przede wszystkim prosty model, przewidywalne dane i kontrola nad capacity. W praktyce warto zadbać o kilka elementów jednocześnie, bo sam wybór trybu nie zapewni stabilności. Najważniejsze działania to:

  • utrzymanie schematu gwiazdy i ograniczenie kardynalności,
  • dopasowanie układu danych do typowych filtrów raportowych,
  • planowanie warm-up dla krytycznych raportów,
  • oddzielanie ciężkich obciążeń od pracy użytkowników.
icon

Formularz kontaktowyContact form

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