Debugowanie M w Power Query: 9 technik (profilowanie, podglądy, diagnostyka kroków)
Praktyczny przewodnik po debugowaniu języka M w Power Query. 9 technik: profilowanie, podglądy kroków, try/otherwise, diagnostyka, pomiar czasu i analiza foldingu na przykładzie.
1. Wprowadzenie: czym jest debugowanie M w Power Query i kiedy jest potrzebne
Power Query to środowisko do pobierania i przekształcania danych, a język M jest jego „silnikiem” opisującym kolejne kroki transformacji. Debugowanie M to zestaw praktyk, które pomagają zrozumieć, co dokładnie dzieje się z danymi na każdym etapie, dlaczego wynik jest inny niż oczekiwany oraz skąd biorą się błędy i spadki wydajności. W praktyce oznacza to świadome sprawdzanie danych wejściowych, inspekcję kroków i ich efektów, weryfikację założeń oraz obserwację, gdzie i dlaczego zapytanie zachowuje się inaczej, niż sugeruje interfejs.
Warto odróżnić debugowanie w Power Query od klasycznego debugowania w językach programowania. Zamiast „uruchamiania programu linia po linii” częściej pracuje się na krokach zapytania i ich wynikach, a problemy wynikają nie tylko z logiki, ale też z: typów danych, niejednoznacznych wartości, jakości źródeł, sposobu odświeżania oraz mechanizmów takich jak składanie zapytań do źródła (folding) czy pamięć podręczna podglądu. Debugowanie M jest więc jednocześnie analizą danych, logiki transformacji i zachowania silnika wykonawczego.
Debugowanie jest potrzebne szczególnie wtedy, gdy:
- Zapytanie kończy się błędem (np. konwersje typów, brakujące kolumny, nieoczekiwane wartości), a komunikat nie wskazuje jednoznacznie przyczyny.
- Wyniki są „prawie poprawne” — pojawiają się pojedyncze rekordy z błędami, duplikaty, ucięte dane, przesunięte nagłówki, źle policzone agregacje lub znikające wiersze po filtrach i połączeniach.
- Odświeżanie jest wolne lub niestabilne — zapytanie działa szybko na podglądzie, ale wolno w pełnym odświeżeniu, albo czas wykonania rośnie po dodaniu pozornie prostego kroku.
- Zachowanie różni się między środowiskami (Power BI Desktop, Excel, usługa w chmurze) lub między odświeżeniami, mimo braku zmian w pliku.
- Zmienia się źródło danych (schemat, nazwy kolumn, formaty dat, kodowanie, zakres danych), a transformacje przestają pasować do nowych warunków.
- Trudno utrzymać i rozwijać zapytanie — rośnie liczba kroków, logika staje się złożona, a ryzyko „popsucia czegoś” przy zmianach jest duże.
Dobrze prowadzone debugowanie ma dwa cele: znaleźć przyczynę problemu (nie tylko objaw) oraz potwierdzić poprawność rozwiązania na danych reprezentatywnych dla rzeczywistych odświeżeń. Dzięki temu Power Query przestaje być „czarną skrzynką”: wiadomo, które kroki są krytyczne, jakie założenia muszą być spełnione przez dane oraz gdzie najczęściej pojawiają się błędy, regresje i wąskie gardła.
2. Przykładowy problem do zdiagnozowania: objawy, dane i cel analizy
Załóżmy typowy scenariusz w Power Query: jedno zapytanie łączy kilka plików (np. cykliczne eksporty) i przygotowuje dane do modelu. Wszystko działało poprawnie, aż nagle odświeżanie zaczyna być wolne, pojawiają się błędy w części wierszy, a wyniki w raporcie przestają się zgadzać z oczekiwaniami. Taki problem jest dobrym kandydatem do debugowania M, bo może wynikać zarówno z jakości danych, jak i z logiki kroków oraz zmian w źródle. Ten wpis powstał w odpowiedzi na zagadnienia, które regularnie pojawiają się na szkoleniach prowadzonych przez Cognity.
Objawy (to, co widzi użytkownik):
- Odświeżanie trwa znacznie dłużej niż wcześniej, czasem kończy się przekroczeniem limitu czasu albo zawieszeniem.
- W podglądzie danych lub po załadowaniu do modelu pojawiają się błędy typu „Error” w pojedynczych komórkach (najczęściej w kolumnach liczbowych i dat).
- Połączenia i scalania dają mniej wierszy niż powinny (część rekordów „znika”), albo przeciwnie — pojawiają się duplikaty.
- Wyniki agregacji (sumy, średnie) są niespójne między odświeżeniami, mimo że użytkownik oczekuje stabilnego wyniku.
- Niektóre kroki działają w Edytorze Power Query, ale po publikacji/odświeżeniu w usłudze (lub po zmianie źródła) pojawiają się rozbieżności.
Jakie dane najczęściej prowadzą do takich problemów:
- Pliki o zmiennej strukturze: czasem dochodzi kolumna, zmienia się nagłówek, pojawia się dodatkowy wiersz z opisem, zmienia się separator lub format daty.
- Mieszane typy w tej samej kolumnie: liczby zapisane jako tekst, daty w różnych formatach, wartości typu „N/A”, „-”, puste ciągi.
- Niejednoznaczne klucze do łączenia: spacje na końcu, różna wielkość liter, wiodące zera, znaki specjalne, różne kodowania.
- Duża skala: dane mieszczą się w podglądzie, ale przy pełnym odświeżeniu rośnie liczba wierszy, a złożone operacje zaczynają dominować czas wykonania.
- Źródła z ograniczeniami: część transformacji nie jest wykonywana po stronie źródła, co skutkuje pobieraniem większej ilości danych i spadkiem wydajności.
Cel analizy w debugowaniu M w takim przypadku jest trójdzielny:
- Zlokalizować krok (lub grupę kroków), w którym pojawia się problem: błąd, nieoczekiwany spadek liczby wierszy, duplikacja lub gwałtowny wzrost czasu.
- Zrozumieć przyczynę: czy to zmiana w danych (format/strukturze), błąd założeń (np. „kolumna zawsze istnieje”), problem z typami, czy też efekt uboczny łączeń i filtrów.
- Określić strategię naprawy: taką, która jednocześnie przywróci poprawność wyników i ograniczy ryzyko powrotu problemu przy kolejnych odświeżeniach.
Ten przykład jest celowo „z życia”: zawiera elementy jakości danych, logiki transformacji i wydajności. Dzięki temu dobrze pokazuje, dlaczego debugowanie w Power Query to nie tylko usuwanie błędów, ale też weryfikowanie założeń, kontrola skutków kolejnych kroków oraz upewnienie się, że wynik końcowy jest stabilny i powtarzalny.
3. Techniki inspekcji danych i kroków: profilowanie kolumn, podglądy kroków, testy na próbkach, izolowanie kroków
Inspekcja w Power Query polega na szybkim „zobaczeniu” danych i skutków kolejnych transformacji, zanim przejdziesz do głębszej analizy logiki, typów czy wydajności. Celem jest wychwycenie momentu, w którym dane zaczynają wyglądać inaczej niż zakładasz: pojawiają się błędy, braki, duplikaty, nieoczekiwane wartości albo zmienia się liczba wierszy.
| Technika | Najlepsza do | Co wykrywa najszybciej | Ryzyko / ograniczenie |
|---|---|---|---|
| Profilowanie kolumn | Kontroli jakości danych | Null/blank, błędy, rozkład wartości, unikalność | Wyniki zależą od tego, czy profil liczony jest na próbce czy na całym zbiorze |
| Podglądy kroków | Szybkiego namierzenia kroku psującego dane | Skoki liczby wierszy/kolumn, „rozjechane” typy, nieoczekiwane przekształcenia | Podgląd nie zawsze odzwierciedla w 100% wynik odświeżenia (np. przy dużych danych) |
| Testy na próbkach | Szybkiej iteracji i eksperymentów | Efekty transformacji na reprezentatywnych rekordach | Próbka może ukryć przypadki brzegowe |
| Izolowanie kroków | Redukcji złożoności i zawężenia źródła problemu | Która część pipeline’u generuje błąd lub „psuje” wynik | Wymaga dyscypliny w budowie zapytań i tymczasowych wariantów |
Profilowanie kolumn: szybki „health-check” danych
Profilowanie kolumn to zestaw metryk i podsumowań wyświetlanych w Edytorze Power Query, które pomagają ocenić jakość danych bez czytania kodu M. W praktyce traktuj je jako pierwszy filtr: czy dane są kompletne, czy mają spodziewany rozkład, czy wartości są spójne.
- Column quality – udział wartości poprawnych, pustych i błędnych; świetne do wychwytywania błędów po merge/expand lub konwersji typów.
- Column distribution – unikalne vs. powtórzone; pomaga wyłapać duplikaty, nieoczekiwane zagęszczenie wartości albo „wybuch” kategorii.
- Column profile – minimum, maksimum, średnia (dla liczbowych), najczęstsze wartości; ułatwia zauważenie odstających danych.
Wskazówka praktyczna: jeśli diagnozujesz problem „czasem działa, czasem nie”, zwróć szczególną uwagę na to, czy profil jest liczony na całym zbiorze czy tylko na podglądzie – wrażliwe przypadki brzegowe mogą nie pojawić się w próbce.
Podglądy kroków: namierzanie momentu zmiany
Power Query buduje transformacje jako sekwencję kroków. Najprostsza diagnostyka polega na „przechodzeniu” po krokach w panelu Applied Steps i obserwowaniu, kiedy dokładnie pojawia się anomalia. To często najszybszy sposób, by ustalić: co się psuje i w którym kroku, zanim zaczniesz analizować dlaczego.
- Porównuj liczbę wierszy i kolumn pomiędzy krokami (skoki są sygnałem ostrzegawczym).
- Patrz na nagłówki, nazwy kolumn i ich kolejność (niezamierzone zmiany utrudniają dalsze kroki).
- Wychwytuj, czy błędy pojawiają się po konkretnych operacjach: rozwinięciu kolumny, podziale, pivocie/unpivocie, łączeniu tabel.
Do szybkiej inspekcji w kodzie M przydaje się podejrzenie „kształtu” tabeli (nazwy kolumn, kilka pierwszych wierszy) – jako tymczasowy krok diagnostyczny:
// Tymczasowy podgląd kilku wierszy
= Table.FirstN(PreviousStep, 50)
Testy na próbkach: szybciej sprawdzaj hipotezy
Gdy problem pojawia się dopiero po serii transformacji, testowanie na pełnym zbiorze spowalnia iterację. Wtedy warto pracować na mniejszej próbce, aby szybko sprawdzić, czy dana operacja działa zgodnie z oczekiwaniem.
- Próbka „pierwsze N” – dobra do weryfikacji formatów, nazw kolumn, podstawowych efektów transformacji.
- Próbka filtrowana – celuj w rekordy podejrzane: nietypowe wartości, puste pola, skrajne daty/kwoty.
- Próbka powtarzalna – staraj się wybierać warunki filtra, które stabilnie odtwarzają problem (to podstawa sensownej diagnostyki).
Przykładowy „hak” do pracy na próbce (na czas debugowania):
// Próbka danych do szybkich testów
= Table.SelectRows(PreviousStep, each [Status] = "X")
Izolowanie kroków: redukcja złożoności i zawężanie obszaru poszukiwań
Izolowanie polega na tym, aby tymczasowo uprościć pipeline i odciąć fragmenty, które nie są potrzebne do odtworzenia problemu. Dzięki temu łatwiej ustalisz, czy błąd wynika z danych wejściowych, konkretnej transformacji, czy interakcji kilku kroków.
- „Komentowanie”/pomijanie kroków – twórz warianty zapytania, w których kończysz je wcześniej (np. na kroku tuż przed problemem).
- Rozdzielenie na zapytania pomocnicze – wyprowadź część transformacji do osobnego zapytania (tymczasowo), aby testować ją niezależnie.
- Minimalny przypadek – zostaw tylko te kolumny i kroki, które są konieczne do wywołania objawu; resztę usuń na czas diagnozy.
W praktyce ta technika jest szczególnie użyteczna, gdy objaw jest „daleko” od przyczyny: np. błąd pojawia się na końcu, ale wynika z wcześniejszego kroku, który subtelnie zmienił dane (liczbę wierszy, nazwy kolumn lub zawartość kluczowych pól).
4. Techniki kontroli logiki i typów: śledzenie typów, obsługa błędów (try/otherwise), walidacja założeń
Debugowanie w M często sprowadza się do odpowiedzi na trzy pytania: jaki jest typ danych na danym kroku, co dokładnie psuje się w logice oraz czy dane spełniają założenia, na których opiera się transformacja. Te techniki są mniej o „oglądaniu” danych, a bardziej o kontrolowaniu przepływu i przewidywalności zapytania: wymuszaniu typów, świadomym przechwytywaniu błędów i szybkim wykrywaniu odstępstw od reguł. Doświadczenie Cognity pokazuje, że rozwiązanie tego problemu przynosi szybkie i zauważalne efekty w codziennej pracy — zwłaszcza gdy zapytania rosną i zaczynają „psuć się” dopiero po kolejnych krokach lub w odświeżaniu.
Śledzenie typów: kiedy „wygląda dobrze” nie znaczy „jest poprawnie”
W Power Query te same wartości mogą wizualnie wyglądać identycznie, ale mieć inny typ (np. tekst „2026-03-22” vs data). To przekłada się na filtry, sortowania, łączenia, agregacje i porównania. Kontrola typów pomaga znaleźć błędy, które ujawniają się dopiero „później” (np. po scaleniu, w obliczeniach lub w odświeżaniu w usłudze).
- Wymuszanie typów (np. przez kroki ustawiania typu) jako forma „kontraktu” dla dalszej logiki.
- Wykrywanie rozjazdów typów między źródłem a oczekiwaniem (np. liczby jako tekst, daty jako liczby serializowane).
- Śledzenie typów złożonych: różnice między table, record, list i any oraz to, kiedy zapytanie niejawnie przechodzi w „luźny” typ any.
Minimalny przykład kontrolnego podejścia do typów (jako uzupełnienie, nie wzorzec na wszystko):
// Wymuszenie typu na kolumnie (po to, by późniejsze kroki nie działały na "any")
= Table.TransformColumnTypes(Source, { {"Kwota", type number}, {"Data", type date} })
Obsługa błędów: try/otherwise jako narzędzie diagnostyczne i ochronne
Błąd w M bywa „twardy” (przerywa odświeżanie) albo „miękki” (pojawia się jako wartości błędów w tabeli). try/otherwise pozwala kontrolować oba scenariusze: zidentyfikować źródło problemu, a w razie potrzeby zastąpić awarię wartością domyślną lub czytelnym komunikatem.
- Diagnostyka: przechwycenie błędu, by zobaczyć, gdzie i dla jakich danych występuje, zamiast przerywać całe zapytanie.
- Odporność: zamiana błędów na null lub wartość zastępczą, jeśli to uzasadnione biznesowo.
- Kontrola warunkowa: alternatywna ścieżka logiki, gdy dane nie spełniają warunków (np. brak kolumny, inny format).
Przykład: bezpieczna konwersja i awaryjna wartość (tylko jako ilustracja):
// Gdy tekst nie daje się zrzutować na liczbę, zwróć null
= try Number.FromText([KwotaTekst]) otherwise null
Walidacja założeń: szybkie testy spójności przed „poważnymi” krokami
Wiele problemów wynika z ukrytych założeń: że kolumna istnieje, że nie ma duplikatów klucza, że format daty jest jednolity, że zakres wartości mieści się w granicach. Walidacja polega na wstawianiu lekkich „punktów kontrolnych”, które wykryją odchylenia możliwie wcześnie i w możliwie czytelnej formie.
- Walidacja struktury: czy oczekiwane kolumny są obecne i mają sensowne typy.
- Walidacja domeny wartości: czy liczby nie są ujemne (jeśli nie powinny), czy daty są w spodziewanym przedziale.
- Walidacja kluczy: czy klucz do łączenia nie ma nieoczekiwanych duplikatów lub braków.
- Walidacja kompletności: czy nie pojawiły się masowe null po konwersjach i czyszczeniu.
W praktyce walidacja może przyjmować formę prostych warunków i filtrów kontrolnych albo wprowadzenia jawnych „assertów” (np. w logice warunkowej). Celem nie jest rozbudowany system testów, lecz wczesne zatrzymanie lub oznaczenie problemu w miejscu, gdzie przyczyna jest jeszcze czytelna.
Różnice i typowe zastosowania (ściąga)
| Technika | Co wykrywa | Kiedy używać | Ryzyko / pułapka |
|---|---|---|---|
| Śledzenie typów | Niejawne konwersje, kolumny jako any, niezgodności typów | Gdy filtry/sort/łączenia dają dziwne wyniki lub psują się po odświeżeniu | Zbyt późne ustawienie typów może maskować źródło problemu |
| try/otherwise | Konkretną operację powodującą błąd + możliwość degradacji | Gdy pojedyncze rekordy wywracają całość lub chcesz oznaczać wyjątki | Nadużycie może „zamiatać” błędy pod dywan (np. masowe null) |
| Walidacja założeń | Odstępstwa od reguł danych (braki, duplikaty, zakresy) | Przed scaleniami, pivotami, agregacją, logiką biznesową | Zbyt restrykcyjna walidacja może blokować poprawne wyjątki |
Połączenie tych trzech podejść daje zwykle najszybszy efekt: ustal typy (żeby logika działała deterministycznie), przechwytuj błędy (żeby zobaczyć i opisać wyjątki) oraz weryfikuj założenia (żeby nie debugować skutków, tylko przyczyny).
5. Diagnostyka zapytań i pomiar wydajności: Query Diagnostics oraz mierzenie czasu wykonywania
Debugowanie w Power Query to nie tylko szukanie błędów logicznych, ale też lokalizowanie wąskich gardeł: kroków, które spowalniają odświeżanie, generują nadmiarowe zapytania do źródła albo niepotrzebnie powiększają dane w pamięci. W tej sekcji chodzi o dwa uzupełniające się podejścia: narzędzia diagnostyczne (Query Diagnostics) oraz praktyczne mierzenie czasu, aby szybko odpowiedzieć na pytania „który krok jest najdroższy?” i „czy zmiana faktycznie coś poprawiła?”.
Query Diagnostics: do czego służy i kiedy po nie sięgać
Query Diagnostics to zestaw narzędzi w edytorze Power Query, który zbiera ślad wykonania zapytania. Pozwala spojrzeć na odświeżanie jak na sekwencję zdarzeń: co Power Query robi „pod spodem”, ile trwa komunikacja ze źródłem, ile trwa przetwarzanie lokalne oraz czy pojawiają się dodatkowe, nieoczekiwane operacje.
- Gdy odświeżanie jest wolne i nie wiesz, czy winne jest źródło danych, sieć czy transformacje w M.
- Gdy podejrzewasz nadmiarowe zapytania (np. wiele podobnych wywołań do źródła) lub niepotrzebne ponowne obliczanie.
- Gdy chcesz rozdzielić czas na część „pobieranie” vs „przetwarzanie” i ukierunkować optymalizację.
W praktyce Query Diagnostics jest bardziej „analityczne” niż zwykłe patrzenie na czas odświeżania całego zapytania: pomaga zobaczyć strukturę obciążenia, a nie tylko końcowy wynik.
Porównanie: Query Diagnostics vs. ręczny pomiar czasu
| Aspekt | Query Diagnostics | Ręczny pomiar czasu (benchmark) |
|---|---|---|
| Co mierzy | Ślad zdarzeń wykonania (m.in. operacje, czas, interakcje ze źródłem) | Czas wykonania zdefiniowanego fragmentu (zwykle całego zapytania lub wariantów) |
| Główne zastosowanie | Diagnostyka „dlaczego jest wolno” i gdzie powstaje koszt | Szybkie porównanie „przed/po” zmianie (czy jest szybciej i o ile) |
| Poziom szczegółowości | Wysoki (wgląd w przebieg i charakter pracy) | Niski/średni (wynik liczbowy do porównań) |
| Kiedy wybrać | Gdy nie znasz przyczyny problemu lub podejrzewasz interakcje ze źródłem | Gdy masz hipotezę optymalizacji i chcesz ją szybko zweryfikować |
Jak sensownie mierzyć czas wykonania (bez „fałszywych” wniosków)
W Power Query pomiar czasu bywa zdradliwy, bo na wyniki wpływa m.in. buforowanie, cache podglądu i to, czy krok faktycznie jest wykonywany w całości. Dlatego warto przyjąć prostą, powtarzalną praktykę pomiaru:
- Ustal stały punkt pomiaru: ten sam zakres danych, to samo zapytanie, to samo środowisko (np. te same ustawienia prywatności i to samo źródło).
- Porównuj warianty (A/B): zmieniaj jedną rzecz naraz (np. kolejność kroków, filtrację, typy), a nie cały zestaw transformacji.
- Wykonuj kilka prób i patrz na medianę, nie pojedynczy odczyt (wahania sieci i cache potrafią zniekształcić wynik).
- Mierz „odświeżenie”, nie tylko podgląd: podgląd w edytorze może nie reprezentować realnego kosztu pełnego przetworzenia.
Minimalny benchmark w M (jako uzupełnienie)
Jeśli potrzebujesz bardzo prostego testu „ile to trwa” dla wybranego wyrażenia, możesz skorzystać z zegara systemowego. To nie zastępuje Query Diagnostics, ale pozwala szybko porównać dwie wersje rozwiązania.
let
t0 = DateTimeZone.UtcNow(),
wynik = /* Twoje wyrażenie lub krok do porównania */,
t1 = DateTimeZone.UtcNow(),
czas = t1 - t0
in
[Czas = czas, Wynik = wynik]
Uwaga praktyczna: takie mierzenie ma sens głównie do porównań wariantów w tych samych warunkach. Wynik „czas” jest miarodajny dopiero wtedy, gdy wymuszasz rzeczywiste wykonanie kosztownych operacji (a nie tylko „leniwy” podgląd).
Co uznawać za sygnały problemów wydajnościowych
Niezależnie od narzędzia, podczas diagnostyki wydajności zwykle szukasz sygnałów, że zapytanie robi więcej pracy niż powinno:
- Długi czas pobierania w porównaniu do przetwarzania: sugeruje, że ograniczenia (np. filtr) nie są stosowane wcześnie lub źródło jest obciążone.
- Długi czas przetwarzania lokalnego: wskazuje na kosztowne transformacje (sortowania, złączenia, grupowania) wykonywane na dużym wolumenie.
- Niestabilny czas między odświeżeniami: często oznacza wpływ cache, sieci lub zmienność źródła; wtedy szczególnie przydaje się seria pomiarów i diagnostyka śladu.
Efekt tej sekcji: decyzja „co dalej”
Po krótkiej rundzie z Query Diagnostics i/lub benchmarkiem czasowym powinnaś/powinieneś umieć odpowiedzieć na dwa pytania:
- Gdzie jest koszt? (pobieranie vs lokalne przetwarzanie, jeden krok vs cała sekwencja)
- Czy zmiana działa? (twarde porównanie czasu „przed/po”)
To wystarcza, by ukierunkować dalsze działania optymalizacyjne i ograniczyć debugowanie metodą prób i błędów.
6. Analiza zapytań pod kątem foldingu: jak wykrywać, dlaczego się psuje i jak go przywracać
Query folding (składanie zapytania) to mechanizm, w którym Power Query „przepycha” jak najwięcej transformacji do źródła danych (np. SQL, OData), zamiast wykonywać je lokalnie w silniku M. Z perspektywy debugowania ma to dwa główne znaczenia: pomaga wyjaśnić dlaczego coś działa wolno oraz dlaczego wynik różni się od oczekiwań (np. przez inne reguły porównań, sortowania czy zaokrągleń po stronie źródła).
Nie każde źródło wspiera folding i nie każda operacja da się złożyć. Dlatego w praktyce debugowanie foldingu polega na: (1) szybkim wykryciu, czy folding jest aktywny w kluczowych krokach, (2) zidentyfikowaniu kroku, który go „łamie”, oraz (3) przeprojektowaniu fragmentu zapytania tak, by maksymalnie dużo pracy wróciło do źródła.
Jak wykrywać folding
- Opcja „Wyświetl zapytanie natywne” (View Native Query) na kroku w Edytorze Power Query: jeśli jest dostępna, to znaczy, że do tego kroku Power Query potrafi wygenerować zapytanie po stronie źródła. Jeśli jest wyszarzona/nieaktywna, folding najpewniej został przerwany wcześniej (albo źródło nie wspiera foldingu).
- Porównanie zachowania po zmianie kolejności kroków: jeśli przesunięcie filtra/wyboru kolumn wcześniej nagle przyspiesza odświeżanie, często oznacza to, że wcześniejsze kroki zaczęły się składać, a późniejsze przestały łamać folding.
- „Podejrzenie” w podglądzie: przy dużych danych częstym sygnałem braku foldingu jest nagły wzrost czasu ładowania podglądu po dodaniu konkretnego kroku, mimo że operacja wygląda „prosto” (np. dodanie kolumny niestandardowej). To nie dowód, ale dobry trop do dalszej weryfikacji.
Co daje folding (i kiedy jest kluczowy)
| Aspekt | Gdy folding działa | Gdy folding jest przerwany |
|---|---|---|
| Wydajność | Źródło filtruje/agreguje, mniejszy transfer danych | Power Query pobiera więcej danych i liczy lokalnie |
| Skalowalność | Łatwiej obsłużyć miliony wierszy | Szybciej pojawiają się limity pamięci/czasu |
| Obciążenie | Więcej pracy po stronie serwera/źródła | Więcej pracy na komputerze/usłudze odświeżania |
| Deterministyczność | Wynik zależy od logiki źródła (np. sort, collation) | Wynik zależy od silnika M i jego reguł |
W debugowaniu M folding jest szczególnie ważny przy: dużych tabelach, łączeniach (join), grupowaniach (group by), filtrach oraz transformacjach tekstu/daty/liczb, które mogą mieć inne semantyki w źródle niż w M.
Dlaczego folding się psuje: typowe przyczyny
- Operacje nieobsługiwane przez źródło: część funkcji M (zwłaszcza niestandardowe przekształcenia w
each ...) nie ma odpowiednika po stronie SQL/OData. - Kroki „materializujące” dane: działania wymuszające pobranie danych do lokalnego silnika (np. niektóre operacje na buforze, złożone kolumny niestandardowe, transformacje binarne/pliki) często kończą folding.
- Zmiana kontekstu danych: przejście z tabeli źródłowej do struktury, której źródło nie „rozumie” (np. agresywne przekształcenia zagnieżdżeń, nietypowe kombinacje pivot/unpivot, manipulacje na rekordach/listach), może przerwać możliwość translacji.
- Łączenie różnych źródeł: mieszanie konektorów (np. baza + plik) zwykle sprawia, że co najmniej część logiki musi wykonać się lokalnie.
- Wstawienie kroku w złym miejscu: nawet jeśli dana transformacja byłaby składana, wykonanie jej po kroku, który już przerwał folding, nie „naprawi” sytuacji.
Jak przywracać folding: praktyczne strategie
Przywracanie foldingu to zazwyczaj nie „magiczna opcja”, tylko zmiana konstrukcji zapytania tak, aby trudne operacje wykonać później (już po maksymalnym odfiltrowaniu danych), a łatwe i składane — jak najwcześniej.
- Przesuwaj filtry i wybór kolumn jak najbliżej źródła: najpierw ogranicz wiersze i kolumny, potem dodawaj kosztowne obliczenia.
- Zastępuj kolumny niestandardowe składanymi transformacjami, jeśli to możliwe: zamiast rozbudowanego
eachrozważ kombinację prostszych kroków (np. wbudowane operacje tekstowe/daty) — wiele z nich ma większą szansę na translację. - Uprość łączenia i grupowania: czasem pomocne jest wykonanie join/agregacji po stronie źródła (np. widok, zapytanie SQL, endpoint), a w Power Query jedynie „doszlifowanie” wyniku.
- Unikaj kroków, które wymuszają lokalne obliczenia, zanim odfiltrujesz dane: jeśli wiesz, że dany krok łamie folding, przenieś go możliwie późno w łańcuchu.
- Rozdziel zapytanie na etapy: jeden etap maksymalnie składany (czyste pobranie/filtry/joiny), drugi etap na końcowe obliczenia lokalne. To często ułatwia też diagnozę miejsca, w którym folding się urywa.
Minimalny przykład: krok, który często łamie folding
Poniżej przykład ilustruje ideę: niestandardowa logika w Table.AddColumn może przerwać folding, podczas gdy proste filtrowanie/wybór kolumn zwykle się składa (konkretne zachowanie zależy od źródła).
let
Source = ...,
KeepCols = Table.SelectColumns(Source, {"A", "B", "C"}),
Filtered = Table.SelectRows(KeepCols, each [A] > 0),
Custom = Table.AddColumn(Filtered, "Flag", each if Text.StartsWith([B], "X") then 1 else 0)
in
CustomW debugowaniu foldingu kluczowe jest ustalenie, na którym kroku przestaje być dostępne „Wyświetl zapytanie natywne”. Jeśli folding urywa się na Custom, to typowy kierunek naprawy to: przenieść tę logikę później (po maksymalnym ograniczeniu danych) albo zastąpić ją transformacją, która ma szansę złożyć się do źródła.
Na co uważać podczas analizy foldingu
- Folding może być częściowy: część kroków składa się do źródła, a część liczy lokalnie. Celem nie zawsze jest „100% foldingu”, tylko składanie najdroższych operacji (filtry, joiny, agregacje).
- Znaczenie kolejności kroków: dwa identyczne zestawy transformacji mogą mieć różną wydajność, jeśli w jednym wariancie folding urwie się wcześniej.
- Różnice semantyczne: gdy folding działa, porównania tekstów, sortowanie czy obsługa nulli mogą być zgodne z regułami źródła (np. collation). Gdy nie działa — z regułami silnika M. To ważna wskazówka w diagnozowaniu „dziwnych” rozbieżności wyników.
7. Debugowanie krok po kroku na przykładzie: dojście do przyczyny i poprawka
Załóżmy typowy scenariusz: zapytanie w Power Query działało poprawnie, po odświeżeniu zaczęło zwracać zaskakująco mało wierszy, a część kolumn kończy się błędami lub wartościami pustymi. Celem debugowania nie jest „zgadywanie”, tylko zawężenie miejsca, w którym wynik przestaje spełniać oczekiwania, oraz znalezienie konkretnej przyczyny (dane, typy, logika kroku, łączenie, filtr, transformacja).
Poniżej przebieg debugowania w trybie „krok po kroku”, który można zastosować do większości problemów w M, bez wchodzenia w szczegóły narzędzi.
- Krok 1: Zdefiniuj objaw w kategoriach mierzalnych
Zanim cokolwiek zmienisz, nazwij problem precyzyjnie: czy chodzi o liczbę wierszy, kompletność kolumn, pojawienie się błędów, brak oczekiwanych kategorii, zmianę agregacji, czy spowolnienie. Taki „miernik” pozwala jednoznacznie stwierdzać, czy jest lepiej lub gorzej po każdej próbie. - Krok 2: Cofnij się do ostatniego „pewnego” kroku
Przejdź po krokach w panelu Zastosowane kroki i znajdź moment, w którym dane są jeszcze poprawne. To jest punkt startowy. Jeśli nie wiesz, gdzie, zacznij od końca i cofnij się o kilka kroków, obserwując kiedy wynik się „łamie”. - Krok 3: Zawęź problem metodą połowienia
Gdy zapytanie ma dużo transformacji, najszybciej dojdziesz do źródła, dzieląc je na połowy: sprawdź stan mniej więcej w połowie kroków, potem w ćwiartce itd. Zamiast iść liniowo przez 40 kroków, szybko lokalizujesz 2–3 kroki, które zmieniają wynik w sposób nieoczekiwany. - Krok 4: Sprawdź, czy „błąd” nie jest skutkiem ubocznym wcześniejszej zmiany
Często wina nie leży w kroku, który pokazuje błąd, tylko w wcześniejszym kroku, który podmienił typ, nazwy kolumn, wartości kluczowe lub usunął wiersze. Dlatego patrz na krok „pierwszego pogorszenia”, a nie na krok „pierwszego czerwonego błędu”. - Krok 5: Oceń, jaki to typ problemu
W praktyce większość awarii wpada do jednej z grup:- problem z typami (np. liczby jako tekst, daty w innym formacie, nieoczekiwane wartości null),
- problem z kluczem (łączenie tabel przestaje pasować, pojawiają się duplikaty lub brak dopasowań),
- problem z filtrem (warunek zaczyna odcinać większość danych po zmianie wartości),
- problem ze strukturą (zmieniła się nazwa kolumny, kolejność, zagnieżdżenie, nagłówki),
- problem z wydajnością (operacje „ciężkie” i nieoczekiwane pobranie pełnych danych).
- Krok 6: Zidentyfikuj minimalny zestaw danych, na którym problem jest widoczny
Żeby nie walczyć z tysiącami wierszy, znajdź kilka rekordów reprezentujących problem: jeden, który działa, i jeden, który się psuje. Kluczowe jest, by umieć powiedzieć: „ten konkretny wiersz znika po kroku X” albo „ta wartość zmienia typ po kroku Y”. - Krok 7: Porównaj oczekiwany i rzeczywisty wynik na tym samym etapie
W punkcie, w którym pojawia się rozjazd, zadaj proste pytania kontrolne: czy liczba wierszy jest sensowna, czy wartości kluczowe są kompletne, czy kolumny mają typ i postać zgodną z założeniem, czy nie pojawiły się duplikaty. Wystarczy kilka obserwacji, by wskazać winowajcę (np. „po konwersji typów część dat staje się pusta”). - Krok 8: Zlokalizuj przyczynę „technicznie” i wybierz strategię poprawki
Kiedy wiesz, że problem wynika np. z typów lub klucza, wybierasz poprawkę, która jest odporna na zmiany danych. Najczęstsze strategie to:- Uodpornienie na typy i formaty: zamiast zakładać jeden format, dopuszczasz warianty i kontrolujesz skutki (np. wartości puste zamiast błędu),
- Stabilizacja kluczy do łączenia: normalizacja (spacje, wielkość liter), kontrola duplikatów, upewnienie się, że klucz nie zawiera null,
- Ostrożne filtrowanie: warunki oparte o stabilne reguły, a nie przypadkowe wartości, które mogą się zmienić,
- Porządek transformacji: najpierw kroki „porządkujące” (nazwy, typy, brakujące), potem „logiczne” (łączenia, grupowania), żeby błędy nie propagowały się w dół.
- Krok 9: Zweryfikuj poprawkę i dodaj „bezpieczniki”
Po zmianie wróć do miernika z Kroku 1: liczba wierszy, brak błędów, kompletność kolumn, spójność kategorii. Jeśli problem wraca po zmianie źródła, warto dodać proste punkty kontrolne w logice zapytania (np. kontrolę, czy klucz nie jest pusty, czy liczba wierszy nie spada drastycznie). Takie „bezpieczniki” nie muszą być rozbudowane — mają szybko sygnalizować, że dane przestały spełniać założenia. - Krok 10: Uprość zapytanie tam, gdzie to możliwe
Debugowanie często ujawnia kroki nadmiarowe: powielone zmiany typów, filtrowanie w kilku miejscach, łączenia wykonywane zbyt wcześnie. Uproszczenie (mniej kroków, bardziej jednoznaczne transformacje) zmniejsza ryzyko kolejnych błędów i ułatwia przyszłe diagnozy.
W skrócie: debugowanie w M to systematyczne zawężanie miejsca problemu, klasyfikacja jego rodzaju (typy, klucze, filtry, struktura, wydajność) oraz wdrożenie poprawki, która jest odporna na zmienność danych. Dzięki temu nie tylko „naprawiasz odświeżenie”, ale też stabilizujesz zapytanie na przyszłość.
Podsumowanie i checklista: szybki proces debugowania oraz najczęstsze pułapki
Debugowanie M w Power Query to połączenie inspekcji danych (co faktycznie znajduje się w każdym kroku), kontroli logiki (czy transformacje robią to, co zakładasz) oraz diagnostyki wydajności (dlaczego odświeżanie trwa długo lub nagle spowalnia). Najczęściej potrzebujesz go wtedy, gdy wynik jest niepoprawny mimo „braku błędów”, gdy pojawiają się błędy tylko w odświeżaniu, a nie w podglądzie, albo gdy po drobnej zmianie zapytanie staje się wielokrotnie wolniejsze.
W praktyce skuteczne debugowanie polega na szybkim zawężaniu problemu: który krok wprowadza błąd, jakie dane go wywołują i dlaczego Power Query zachowuje się inaczej niż oczekujesz (np. przez typy, kontekst źródła lub brak foldingu).
Szybki proces debugowania (w 9 krótkich krokach)
- Zdefiniuj objaw: czy problem dotyczy wartości, liczby wierszy, duplikatów, braków, błędów, czy czasu odświeżania.
- Ustal punkt odniesienia: w którym miejscu wynik był jeszcze „dobry” (lub jaka wersja/odświeżenie działało poprawnie).
- Sprawdź podgląd danych po krokach: porównuj liczbę wierszy, rozkłady wartości i nietypowe rekordy.
- Wyizoluj podejrzany fragment: tymczasowo wyłącz/oddziel część kroków, aby znaleźć pierwszy krok, który zmienia dane w niepożądany sposób.
- Zweryfikuj założenia: czy kolumny mają oczekiwane typy, czy wartości nie zawierają ukrytych znaków, czy klucze łączeń są spójne.
- Przetestuj na próbkach i skrajnych przypadkach: osobno sprawdź rekordy „podejrzane” (puste, nietypowe formaty, wartości graniczne).
- Odseparuj błędy od danych: rozróżnij błędy wynikające z logiki transformacji od błędów danych wejściowych.
- Oceń wydajność: ustal, czy spowolnienie wynika z konkretnego kroku, źródła, czy przeniesienia obliczeń do lokalnego silnika.
- Wprowadź minimalną poprawkę i potwierdź efekt: napraw jeden problem naraz, a potem wróć do pełnego zestawu danych i pełnego odświeżenia.
Checklista: co sprawdzić, zanim uznasz, że „to błąd Power Query”
- Typy danych: czy typy są ustawione świadomie, a nie „automatycznie”; czy liczby nie są tekstem; czy daty nie zależą od ustawień regionalnych.
- Null vs pusty tekst vs zero: czy logika nie traktuje tych przypadków zamiennie.
- Błędy ukryte w kolumnach: pojedyncze rekordy z błędem potrafią „zatruć” kolejne kroki (sortowanie, grupowanie, scalanie).
- Niejawne przycinanie i czyszczenie: spacje wiodące/końcowe, znaki niedrukowalne, różne warianty tego samego klucza.
- Operacje łączenia: niezgodność typów kluczy, różne formaty, duplikaty po obu stronach, nieoczekiwany typ joinu.
- Kolejność kroków: zbyt wczesne usunięcie kolumn, filtrowanie przed normalizacją, zmiana typów po operacjach wymagających spójnych formatów.
- Różnica między podglądem a odświeżeniem: podgląd to zwykle tylko część danych; problemy mogą ujawniać się dopiero na pełnym wolumenie.
- Parametry i zapytania pomocnicze: czy nie wprowadzają innego zakresu danych niż zakładasz (np. filtr dat).
- Źródło danych: zmiany schematu, brak uprawnień, limity API, czasowe błędy połączenia, nieaktualne metadane.
- Folding: czy kluczowe kroki nadal „składają się” do źródła; jeśli nie, to czy nie powoduje to lawinowego spowolnienia.
Najczęstsze pułapki w debugowaniu M
- „U mnie działa” na podglądzie: wnioski wyciągane z kilkudziesięciu wierszy zamiast z pełnego zestawu danych.
- Przypadkowe poleganie na lokalnych ustawieniach: szczególnie przy datach i liczbach (formaty, separatory, strefy czasowe).
- Maskowanie problemu zamiast naprawy: usuwanie błędów bez zrozumienia ich przyczyny prowadzi do cichych przekłamań.
- Nadmierna „magia” automatycznych kroków: automatyczne typowanie czy automatyczne nagłówki potrafią zmienić się po aktualizacji danych.
- Brak kontroli nad logiką filtrów: filtry zależne od bieżącej daty, strefy czasowej lub niejednoznacznych warunków.
- Nieświadome powielanie pracy: wielokrotne przeliczanie tego samego, zbyt częste odwołania do kosztownych kroków pośrednich.
- Traktowanie wydajności jako „problem po fakcie”: drobna zmiana może przenieść ciężar obliczeń z serwera na lokalny silnik i nagle wszystko zwalnia.
Jeśli podejdziesz do debugowania jak do procesu eliminacji: najpierw lokalizujesz krok, potem potwierdzasz przyczynę na danych, a na końcu mierzysz wpływ poprawki, większość problemów w M da się rozwiązać szybko i bez chaotycznego „klikania na oślep”.
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 Debugowanie M w Power Query: 9 technik (profilowanie, podglądy, diagnostyka kroków)
Najlepiej zacząć od wskazania pierwszego kroku, w którym dane przestają wyglądać poprawnie. W praktyce przechodzisz po Applied Steps, porównujesz liczbę wierszy, kolumn i pojawienie się błędów. Taki przegląd zwykle szybciej pokazuje źródło problemu niż analiza całego kodu M od początku do końca.
Profilowanie kolumn pomaga wtedy, gdy problem wynika z jakości danych, a nie tylko z samej logiki transformacji. Najszybciej wykrywa błędy, puste wartości, rozjazdy unikalności i nietypowy rozkład danych. To szczególnie przydatne po merge, expand i zmianach typów, gdy pojedyncze rekordy zaczynają psuć dalsze kroki.
Podgląd może różnić się od pełnego odświeżenia, bo często nie reprezentuje całego zbioru danych. W artykule podkreślono, że na wynik wpływają próbki, cache podglądu i skala danych. Dlatego zapytanie może wyglądać poprawnie w edytorze, a dopiero na pełnym odświeżeniu ujawnić błędy typów, brakujące kolumny albo problemy wydajnościowe.
try/otherwise warto stosować jako narzędzie diagnostyczne, a nie sposób na bezrefleksyjne maskowanie błędów. Najlepiej używać go tam, gdzie pojedyncze wartości mogą wywołać błąd, ale chcesz zobaczyć wyjątki i zachować ciągłość zapytania. Jeśli po zastosowaniu tej konstrukcji nagle pojawia się dużo nulli, to sygnał, że trzeba wrócić do przyczyny.
Problem z typami danych zwykle widać po tym, że wartości wyglądają poprawnie, ale filtry, sortowanie, łączenia albo obliczenia dają zły wynik. Typowe sygnały to błędy po konwersji, daty interpretowane niespójnie i liczby zapisane jako tekst. Pomaga świadome ustawienie typów oraz sprawdzenie, czy kolumny nie działają na zbyt luźnym typie any.
Najczęściej poznasz to po tym, że opcja „Wyświetl zapytanie natywne” przestaje być dostępna na kluczowym kroku. Dodatkowym sygnałem bywa nagły wzrost czasu odświeżania po pozornie prostej zmianie. Gdy folding się urywa, Power Query zaczyna wykonywać więcej pracy lokalnie, co szczególnie boli przy dużych tabelach, filtrach, joinach i agregacjach.
Najczęściej pomaga przesunięcie prostych, składanych operacji jak najbliżej źródła danych. W praktyce warto sprawdzić przede wszystkim:
- czy filtry i wybór kolumn są wykonane wcześnie,
- czy złożone kolumny niestandardowe nie pojawiają się za wcześnie,
- czy część joinów lub agregacji nie powinna być uproszczona,
- czy zapytanie nie miesza źródeł wymuszających obliczenia lokalne.
Najskuteczniej działa izolowanie fragmentów zapytania i sprawdzanie ich na małej, powtarzalnej próbce danych. Zamiast analizować każdy krok po kolei, możesz zawężać obszar metodą połowienia. Pomaga też prosty schemat pracy:
- znajdź ostatni poprawny krok,
- wyodrębnij podejrzany fragment,
- porównaj oczekiwany i rzeczywisty wynik,
- potwierdź poprawkę na pełnym odświeżeniu.