DAX query plan w praktyce: jak czytać Server Timings i wyłapać najdroższe miary

Praktyczny przewodnik po DAX Studio: jak czytać Server Timings i Query Plan, rozróżniać koszt FE/SE oraz wskazać najdroższe miary. Checklista i przykłady „wolny vs szybszy”.
18 maja 2026
blog

1. Wprowadzenie: kiedy i po co analizować wydajność DAX

Wydajność raportu w Power BI lub w modelu tabularnym rzadko jest „tylko problemem DAX” albo „tylko problemem modelu”. Najczęściej to efekt interakcji trzech elementów: modelu danych (struktura, relacje, kardynalność), miar (logika obliczeń i sposób pracy z kontekstem) oraz kontekstu zapytania generowanego przez wizualizacje (filtry, poziomy agregacji, układ osi). Analiza wydajności DAX ma sens wtedy, gdy chcesz zrozumieć, który z tych elementów jest faktycznym źródłem kosztu i jak go ograniczyć bez zgadywania.

Praktycznie: dwie miary o podobnej logice mogą działać zupełnie inaczej w zależności od tego, czy są liczone dla jednej wartości (np. karta), dla wielu grup (np. tabela), czy w warunkach wielu jednoczesnych filtrów. Z kolei dobrze napisany DAX nie uratuje sytuacji, jeśli model wymusza kosztowne skany dużych tabel lub jeśli relacje i kierunki filtrowania generują nieprzewidywalnie szeroki kontekst.

Wydajność warto analizować szczególnie, gdy:

  • Wizualizacje „mielą” lub odświeżają się długo po zmianie slicera, mimo że dataset nie jest ogromny.
  • Raport działa dobrze na poziomie agregacji, ale dramatycznie zwalnia po zejściu do szczegółów (np. drill-down, tabela z wieloma wierszami).
  • Jedna miara spowalnia cały widok — nawet jeśli inne miary są szybkie.
  • Problem jest trudny do odtworzenia i pojawia się tylko w określonych kombinacjach filtrów.
  • Po zmianie modelu (nowa relacja, dodatkowa tabela, zmiana kolumny w osi) czas odpowiedzi wyraźnie się pogorszył.

Po co robi się analizę z użyciem planu zapytania i metryk czasowych? Żeby odpowiedzieć na kilka kluczowych pytań, które prowadzą do konkretnych działań optymalizacyjnych:

  • Która miara jest najdroższa w danym kontekście wizualizacji, a nie „w teorii”.
  • Czy koszt wynika głównie z pracy silnika magazynującego dane (odczyt i agregacje) czy z warstwy obliczeniowej (logika DAX, iteracje, przejścia kontekstu).
  • Czy problem jest lokalny (pojedyncza miara lub fragment logiki), czy systemowy (model, relacje, zbyt szczegółowe zapytania).
  • Jak zmienia się koszt po modyfikacji miary, układu wizualizacji lub filtra — czyli czy optymalizacja faktycznie działa.

Kluczowym pojęciem w tym miejscu jest kontekst zapytania. To on determinuje, ile razy miara musi zostać policzona oraz na jakim zbiorze danych. Ten sam zapis DAX może być lekki w kontekście pojedynczej wartości, a kosztowny w kontekście wielu grup, gdzie obliczenie jest powtarzane wielokrotnie. Dlatego analiza wydajności nie polega na ocenianiu formuły „na oko”, tylko na obserwacji, jak silnik ją wykonuje dla konkretnego zapytania wysłanego przez raport.

W dalszej pracy celem nie jest „mikrooptymalizacja” każdej miary, lecz zbudowanie nawyku: najpierw zidentyfikować rzeczywisty koszt, potem wskazać, czy problem leży w modelu, w miarze, czy w kontekście, a dopiero na końcu dobrać technikę poprawy. Taka kolejność pozwala szybko wyłapać kilka najbardziej kosztownych miejsc, które odpowiadają za większość czasu odpowiedzi.

2. Przygotowanie środowiska: instalacja i podłączenie DAX Studio oraz konfiguracja śledzenia

Zanim zaczniesz interpretować czasy z Server Timings i szczegóły z Query Plan, warto przygotować środowisko tak, aby pomiary były powtarzalne i porównywalne. Ten etap ma jeden cel: uruchomić DAX Studio w trybie, w którym widzisz to samo zapytanie, które rzeczywiście wykonuje się w silniku modelu (Power BI lub SSAS Tabular), oraz włączyć śledzenie, które zapisze metryki potrzebne do dalszej analizy. Podczas szkoleń Cognity ten temat wraca regularnie – dlatego zdecydowaliśmy się go omówić również tutaj.

Instalacja DAX Studio

DAX Studio jest darmowym narzędziem dla modeli tabular. Najczęściej instaluje się je lokalnie na komputerze, na którym uruchamiasz Power BI Desktop lub masz dostęp do instancji SSAS Tabular. Po instalacji kluczowe jest tylko jedno: uruchamiaj DAX Studio w kontekście tego samego użytkownika i środowiska, w którym wykonujesz testy — ogranicza to różnice wynikające z uprawnień, pamięci podręcznej i połączeń.

Podłączenie do Power BI Desktop

W przypadku Power BI Desktop DAX Studio łączy się z lokalnie uruchomioną instancją silnika tabular, która działa „w tle” otwartego pliku PBIX. W praktyce oznacza to, że:

  • Power BI Desktop musi być uruchomiony, a plik z modelem otwarty.
  • W DAX Studio wybierasz połączenie do działającej lokalnej instancji Power BI.
  • Analizujesz rzeczywisty model (miary, relacje, kolumny) dokładnie w takim stanie, w jakim jest w PBIX.

To podejście jest najwygodniejsze do pracy nad raportem, bo pozwala od razu testować zmiany w miarach i obserwować ich wpływ na wykonanie zapytań.

Podłączenie do SSAS Tabular (lub modelu tabular w usłudze)

Jeśli pracujesz z modelem wdrożonym na serwerze (SSAS Tabular) lub zdalnie udostępnionym modelem tabular, DAX Studio łączy się po standardowym połączeniu do instancji. Różnica względem Power BI Desktop jest głównie organizacyjna i operacyjna:

  • Zapytania wykonują się na serwerze, więc wyniki zależą m.in. od obciążenia serwera i współdzielenia zasobów.
  • Łatwiej o scenariusze z wieloma użytkownikami i równoległymi odpytywaniami, co może wpływać na czasy.
  • Uprawnienia i role mogą ograniczać widoczność danych i zmieniać kontekst, w jakim działa zapytanie.

Do testów wydajności warto dążyć do możliwie stabilnych warunków: podobny zestaw filtrów, podobny wolumen danych oraz możliwie stałe obciążenie środowiska.

Konfiguracja śledzenia: co włączyć, aby widzieć „koszt” zapytania

W DAX Studio interesują Cię dwa niezależne źródła informacji: Server Timings (czasy i statystyki wykonania) oraz Query Plan (struktura wykonania). Na etapie przygotowania kluczowe jest włączenie zbierania tych danych przed uruchomieniem testowanego zapytania, tak aby wynik obejmował pełen przebieg wykonania.

  • Server Timings – włącz zbieranie metryk wykonania, aby po uruchomieniu zapytania otrzymać zestaw czasów i liczników. To jest podstawowy punkt startowy do diagnozy „co jest drogie”.
  • Query Plan – włącz zbieranie planu, aby móc później powiązać koszt z konkretnymi operatorami i etapami wykonania. Plan bywa bardziej szczegółowy, ale też wymaga ostrożności w interpretacji.

Upewnij się, że uruchamiasz pomiar na tym samym zapytaniu, a nie na jego wariancie. W praktyce oznacza to, że testy najlepiej wykonywać z jednego miejsca: albo z DAX Studio (pisząc zapytanie), albo przez przechwycenie zapytania generowanego przez raport i ponowne uruchomienie go w DAX Studio. Dzięki temu minimalizujesz ryzyko analizowania „innego” zapytania niż to, które spowalnia raport.

Higiena testów: warunki, które pomagają uzyskać wiarygodne wyniki

Różnice w czasie wykonania często nie wynikają ze zmiany miary, tylko z warunków uruchomienia. Warto zadbać o kilka prostych zasad:

  • Powtarzalność – uruchamiaj test kilka razy i porównuj wyniki, zamiast opierać się na pojedynczym pomiarze.
  • Stabilny kontekst – utrzymuj stałe filtry i selekcje, bo zmiana kontekstu zapytania może całkowicie zmienić koszt wykonania.
  • Świadomość cache – pierwsze uruchomienie może być inne niż kolejne; traktuj to jako normalny element testów i oceniaj wyniki w sposób konsekwentny.
  • Minimalizacja zakłóceń – ogranicz równoległe, ciężkie operacje w tle (odświeżenia, inne raporty, importy danych), które mogą fałszować czasy.

Po wykonaniu tych kroków masz gotowe środowisko: DAX Studio jest podłączone do właściwego modelu, a śledzenie jest skonfigurowane tak, abyś mógł przejść do analizy metryk i planu wykonania bez zgadywania, skąd biorą się opóźnienia.

3. Podstawowe metryki w DAX Studio: Duration, CPU, Rows, SE Queries, FE/SE Time — jak je czytać i interpretować

DAX Studio daje dwa szybkie „termometry” wydajności: Server Timings (co i ile czasu wykonywał silnik) oraz metryki podsumowujące wykonanie zapytania. Na tym etapie chodzi o umiejętność czytania liczb i wstępnego rozpoznania, czy problem leży w dostępie do danych (Storage Engine), czy w logice miary (Formula Engine). Poniżej najważniejsze pola, które najczęściej wykorzystuje się do pierwszej diagnozy.

Metryka Co mierzy Jak interpretować (heurystyka) Najczęstsze wnioski
Duration Całkowity czas wykonania zapytania (od startu do końca). To „czas odczuwalny” przez użytkownika. Porównuj między uruchomieniami po wyczyszczeniu cache lub na spójnych warunkach. Wysoki Duration przy niskim CPU sugeruje czekanie (np. na SE, blokady, zasoby). Wysoki Duration i wysoki CPU sugeruje ciężką pracę obliczeniową (często FE).
CPU Łączny czas CPU zużyty przez zapytanie. Może być większy niż Duration (równoległość). Sprawdzaj relację CPU vs Duration. CPU ≫ Duration: równoległa praca SE/FE. CPU ≈ Duration: praca bardziej sekwencyjna lub ograniczona wątkami.
Rows Liczba wierszy przetworzonych/zwróconych przez elementy wykonania (najczęściej w kontekście SE). Nie zawsze oznacza „wiersze tabeli faktów”; często to liczności po filtrach, grupowaniach i agregacjach. Duże Rows w SE to sygnał, że zapytanie „przerzuca” dużo danych (np. przez mało selektywne filtry). Duże Rows w logice iteracyjnej zwykle idzie w parze z kosztami FE.
SE Queries Liczba zapytań wysłanych do Storage Engine (VertiPaq lub DirectQuery). Nie ma jednego „dobrego” progu, ale nagły wzrost liczby zapytań jest często czerwonym światłem. Wiele krótkich SE Queries bywa efektem iteracji w FE, która „odpala” SE wielokrotnie. Nieliczne, ale ciężkie SE Queries mogą wskazywać na problem w skanowaniu/agregacji danych.
SE Time Czas spędzony w Storage Engine. Jeśli dominuje, podejrzewaj koszty skanów, grupowań, słabej selektywności filtrów, wysokiej kardynalności. „Wąskie gardło” po stronie danych: model, kolumny, relacje, sposób filtrowania i agregacji.
FE Time Czas spędzony w Formula Engine (interpretacja DAX, iteracje, materializacje pośrednie). Jeśli dominuje, zwykle problem jest w konstrukcji miary lub w kosztownym kontekście obliczeń. „Wąskie gardło” po stronie logiki: iteratory, złożone CALCULATE, konteksty przejściowe, kosztowne warunki i przekształcenia.

Duration vs CPU: dwie liczby, które mówią najwięcej na start

Najprostszy punkt wyjścia to porównanie Duration i CPU:

  • CPU dużo większe niż Duration — zapytanie korzysta z równoległości (często po stronie SE). To nie musi być problem; istotne jest, czy Duration jest akceptowalne.
  • CPU zbliżone do Duration — praca jest bardziej sekwencyjna; jeśli obie wartości są wysokie, częściej wchodzimy w obszar kosztownego FE lub ograniczeń zasobów.
  • Duration wysokie, CPU relatywnie niskie — możliwe czekanie (np. na SE, I/O, współdzielenie zasobów). To sygnał, by sprawdzić rozkład czasu FE/SE.

FE Time i SE Time: szybka decyzja „gdzie szukać”

Podział na Formula Engine i Storage Engine jest praktyczną osią diagnostyki:

  • Dominuje SE Time — na poziomie miary problemem często jest to, że zapytanie wymusza duże skany lub drogie agregacje. W praktyce oznacza to: sprawdzaj selektywność filtrów, kardynalność kolumn, oraz czy miara nie wymusza niepotrzebnie pracy na dużych zbiorach.
  • Dominuje FE Time — miara najpewniej robi dużo pracy „w pętli” lub materializuje duże tabele pośrednie. Wtedy kluczowe jest ograniczenie iteracji i liczby kontekstów obliczeń.
  • FE i SE są wysokie — często mamy efekt łańcuchowy: FE generuje wiele wywołań do SE lub SE zwraca dużo danych, które FE potem dodatkowo obrabia.

SE Queries i Rows: dwie metryki, które często zdradzają „iterowanie”

SE Queries i Rows warto czytać łącznie, bo razem sugerują charakter obciążenia:

  • Wysokie SE Queries + umiarkowane Rows — typowy zapach „wielu małych strzałów” do SE, często wywoływanych przez iteracje w FE (np. obliczenia per element, per grupa).
  • Niskie SE Queries + bardzo wysokie Rows — mniej zapytań, ale ciężkie skany/agregacje. To częściej temat „kształtu” zapytania i modelu danych.
  • Wysokie Rows zwracane do FE — nawet jeśli SE działa sprawnie, FE może mieć potem kosztowną pracę na dużym zbiorze pośrednim.

Minimalny przykład: metryki jako „kompas”

Poniższy fragment to tylko ilustracja, jak w praktyce myśli się metrykami (bez wchodzenia w analizę planu):

-- Uruchamiasz zapytanie/miarę i patrzysz na:
-- Duration, CPU, FE Time, SE Time, SE Queries, Rows

-- Jeśli widzisz:
-- FE Time: wysokie, SE Time: niskie, SE Queries: wysokie
-- to podejrzenie pada na logikę miary (iteracje) i częste odpytywanie SE.

Najczęstsze pułapki interpretacji (żeby nie wyciągać złych wniosków)

  • Cache: kolejne uruchomienia mogą mieć niższy SE Time, bo dane są już w pamięci. Porównuj wyniki w porównywalnych warunkach.
  • Równoległość: CPU nie jest „błędem” samym w sobie; liczy się wpływ na Duration oraz to, czy zasoby są współdzielone z innymi zapytaniami.
  • Rows nie zawsze = „za dużo danych w modelu”: czasem to efekt chwilowej tabeli pośredniej lub grupowania, a nie samej wielkości tabeli faktów.
  • SE Queries nie zawsze oznacza problem: kilka zapytań bywa normalne; alarmujący jest wzorzec: bardzo dużo zapytań przy rosnącym Duration/FE.

4. Server Timings krok po kroku: identyfikacja najdroższych miar i rozróżnienie kosztu Storage Engine vs Formula Engine

Server Timings w DAX Studio to najszybsza droga, żeby odpowiedzieć na dwa praktyczne pytania: „co dokładnie kosztuje czas?” oraz „czy problem jest w Storage Engine (SE) czy w Formula Engine (FE)?”. W tej sekcji przechodzimy przez typowy workflow analizy jednego zapytania/visuala, bez wchodzenia w szczegółowe reguły optymalizacji. Zespół trenerski Cognity zauważa, że właśnie ten aspekt sprawia uczestnikom najwięcej trudności — dlatego warto mieć prostą procedurę, która porządkuje analizę.

Krok 1: Włącz Server Timings i uruchom pojedyncze zapytanie

  • Po podłączeniu do modelu w DAX Studio włącz Server Timings (panel/zakładka).
  • Uruchamiaj analizę na pojedynczym zapytaniu (jednym visualu albo jednym DAX Query), aby nie mieszać kosztów wielu requestów.
  • W miarę możliwości wyłącz cache (jeśli chcesz zobaczyć „cold” performance) albo testuj konsekwentnie w tej samej konfiguracji, żeby porównania miały sens.

Krok 2: Najpierw patrz na podział FE vs SE (zanim zejdziesz niżej)

Wynik Server Timings w pierwszej kolejności czytaj jako budżet czasu rozbity na dwa silniki:

  • Storage Engine (SE) – wykonuje skany, agregacje, joiny i filtracje na skompresowanych kolumnach (VertiPaq) lub deleguje do źródła w DirectQuery.
  • Formula Engine (FE) – interpretuje logikę DAX, buduje kontekst, wykonuje iteracje, generuje i koordynuje zapytania do SE, „skleja” wyniki.
Jeśli dominuje… Typowa interpretacja Co to zwykle oznacza (na tym etapie)
SE Time Silnik danych spędza dużo czasu na odczycie/obliczeniach. Problem może leżeć w rozmiarze skanów, cardinality, filtrach, relacjach, lub w tym, że miara wymusza ciężkie zapytania do SE.
FE Time Dużo pracy po stronie interpretera DAX. Często iteracje, złożony kontekst (np. wielokrotne przejścia), logika warunkowa, tworzenie tabel pośrednich lub wyrażenia, których SE nie potrafi „przejąć”.
Wysokie oba Zapytanie jest ciężkie w obu warstwach. Zwykle miara generuje wiele kosztownych zapytań do SE i dodatkowo FE wykonuje sporo pracy na wynikach.

Krok 3: Przejdź do listy „SE Queries” i zidentyfikuj kosztowne odpyty

W Server Timings znajdziesz część pokazującą zapytania do Storage Engine (często jako lista z czasami i liczbą wierszy). To Twoja „mapa” tego, ile razy FE musiał poprosić SE o dane oraz jak ciężkie były te prośby.

  • Policz liczbę SE Queries: duża liczba krótkich zapytań często oznacza, że FE iteruje i dla każdej iteracji odpytuje SE (narzut koordynacji i powtarzalności).
  • Wyszukaj najdłuższe pojedyncze SE query: pojedynczy „długi” strzał do SE często wskazuje na szeroki skan lub kosztowną filtrację/join.
  • Zwróć uwagę na Rows: duża liczba zwróconych wierszy w połączeniu z wysokim FE Time bywa sygnałem, że FE musi dalej przetwarzać obszerny wynik zamiast dostać gotową agregację.

Krok 4: Powiąż koszt z miarą/visualem – podejście „izoluj i porównaj”

Server Timings nie zawsze „podaje nazwę miary na tacy”, bo finalne zapytanie visuala może zawierać kilka miar, filtry i logikę generowaną przez klienta. Najprostsza metoda identyfikacji najdroższej miary to porównania A/B:

  • Uruchom zapytanie z jedną miarą (np. usuń pozostałe miary z visuala albo wykonaj osobne zapytanie).
  • Dodawaj miary pojedynczo i obserwuj przyrosty w: SE Time, FE Time, liczbie SE Queries oraz Rows.
  • Jeśli jedna miara powoduje skok FE Time bez dużego wzrostu SE Time, podejrzewaj koszt w logice DAX (iteracje/kontekst).
  • Jeśli jedna miara powoduje skok SE Time lub pojawienie się jednego dominującego SE query, podejrzewaj koszt w skanie/agregacji/filtrach.

Krok 5: Rozpoznaj podstawowe „wzorce” problemów po samych Timingach

Nie wchodząc jeszcze w szczegóły planu zapytania, już same Timingi pozwalają rozróżnić kilka typowych sytuacji:

  • Wiele SE Queries + wysokie FE Time – często wskazuje na iteracyjne wyrażenia, w których FE „kręci pętlę” i wielokrotnie odpytuje SE.
  • Mało SE Queries, ale jedno bardzo długie – typowo ciężki skan albo filtracja po kolumnie o wysokiej kardynalności; SE jest wąskim gardłem.
  • SE Time mały, FE Time duży – SE szybko zwraca dane, ale FE spędza czas na budowie tabel pośrednich, logice warunkowej, łączeniu wyników i obliczeniach poza SE.
  • Duże Rows z SE – sygnał, że do FE trafia zbyt „surowy” zestaw danych (zamiast bardziej zredukowanej agregacji).

Krok 6: Minimalny przykład testu miary (tylko jako narzędzie diagnostyczne)

Jeżeli chcesz szybko przetestować samą miarę w kontrolowanym kontekście, często wystarcza proste zapytanie zwracające jedną wartość (to nie jest jeszcze optymalizacja – tylko izolacja kosztu):

EVALUATE
ROW(
    "Test", [TwojaMiara]
)

Potem porównujesz Server Timings między różnymi miarami lub wariantami tej samej miary, patrząc głównie na to, czy koszt „siedzi” w FE czy w SE.

Krok 7: Co zapisać jako wnioski z Server Timings

Po jednym przebiegu analizy warto spisać 3–5 faktów, które poprowadzą dalsze kroki:

  • Dominujący silnik: FE czy SE?
  • Liczba SE Queries: czy jest ich podejrzanie dużo?
  • Najdroższe SE query: jedno czy kilka?
  • Rows: czy wynik z SE wygląda na zbyt obszerny w stosunku do celu miary?
  • Miary „winne” przyrostu: które miary po dodaniu do visuala powodują największy skok czasu?

Taki zestaw obserwacji zwykle wystarcza, żeby zdecydować, czy dalszą analizę prowadzić „od strony SE” (co i jak jest skanowane) czy „od strony FE” (jaka logika DAX generuje iteracje i dodatkową pracę).

💡 Pro tip: Zacznij od podziału FE vs SE w Server Timings i dopiero potem schodź do szczegółów: liczba SE Queries, najdłuższe pojedyncze zapytanie i Rows zwykle od razu podpowiadają, czy problemem jest iteracja w FE czy ciężki skan w SE. Najszybciej wskażesz „winną” miarę metodą A/B — uruchom visual z jedną miarą i dodawaj kolejne pojedynczo, obserwując skoki w FE Time/SE Time.

5. Query Plan krok po kroku: jak analizować plan, wykrywać iteratory/spool i łączyć wnioski z miarami

Server Timings mówi ile kosztowało zapytanie (FE/SE, liczba zapytań do SE, czas). Query Plan pokazuje natomiast dlaczego — jak silnik rozbił miarę i jakie operatory wykonał po drodze. W praktyce plan jest najszybszą drogą do znalezienia „wąskich gardeł” w logice DAX: iteratorów, przejść kontekstów, materializacji pośrednich wyników (spool) oraz miejsc, w których Formula Engine (FE) musi wykonać dużą pracę w pamięci.

5.1. Co właściwie oglądasz w Query Plan?

W DAX Studio plan zapytania prezentuje drzewo operatorów. Najważniejsze jest, by czytać je od góry do dołu jako przepływ: operator nadrzędny „karmi się” wynikami operatorów podrzędnych. Nie musisz znać wszystkich nazw — na start wystarczy rozróżnić kilka klas elementów:

  • Operatory skanu/agregacji w SE — ślady pracy Storage Engine, zwykle „tanie” jeśli trafiają w dobrze skompresowane kolumny i proste grupowania.
  • Operatory iteracyjne w FE — sygnalizują pętle po wierszach/tabelach, często źródło kosztu CPU oraz długiego FE Time.
  • Materializacja/buforowanie (spool/cache) — pośrednie wyniki są zapisywane i ponownie używane; bywa pomocne, ale często ujawnia, że silnik musi „przekalkulować” coś w pamięci.
  • Przepływ filtrów i kontekstów — elementy planu, które wskazują na aplikowanie filtrów, przejścia kontekstu i łączenie zestawów.

5.2. Minimalny workflow analizy planu (checklista)

  • Krok 1: Zlokalizuj gałąź odpowiadającą miarze — w planie szukaj fragmentów opisujących obliczenia agregacji dla Twojego wyniku (często będzie to najwyższy operator agregujący lub node, pod którym „zbiegają się” filtry i obliczenia).
  • Krok 2: Wypatrz iteratory — pierwsze podejrzenie przy wolnych miarach to operatory sugerujące iterację po wielu wierszach (np. wzorce odpowiadające SUMX/AVERAGEX/iteratorom po tabelach). Jeśli w planie widzisz wiele zagnieżdżonych poziomów iteracji, spodziewaj się wzrostu kosztu wykładniczego przy większej kardynalności.
  • Krok 3: Sprawdź, czy pojawia się spool/materializacja — plan z „spool” oznacza, że silnik tworzy tymczasową strukturę (np. aby ponownie użyć wyniku lub aby obsłużyć złożone filtrowanie/łączenie). Jeden spool nie jest z automatu zły, ale to czerwone światło, że FE wykonuje „pracę organizacyjną”.
  • Krok 4: Oceń, gdzie odbywa się ciężar — jeśli gałąź planu wygląda na „FE-heavy” (dużo iteratorów, spool, złożone operatory), zestaw to z obserwacją z Server Timings: czy faktycznie FE dominuje czas? Gdy SE dominuje, plan częściej pokaże proste skany/agregacje, ale na dużych zbiorach.
  • Krok 5: Zwiąż plan z konkretnym fragmentem DAX — dopiero teraz wróć do miary i zidentyfikuj konstrukcję, która najpewniej mapuje się na podejrzany operator (iterator, zagnieżdżony FILTER, złożony warunek, dynamiczna tabela, itp.).

5.3. Iteratory: jak je rozpoznać i co z nich wynika

W planie iteratory objawiają się gałęziami, w których wynik jest liczony „per wiersz” lub „per grupę”, a następnie agregowany. Z punktu widzenia praktycznej diagnostyki interesują Cię dwa sygnały:

  • Głębokość zagnieżdżenia — iterator w iteratorze to typowy generator kosztu CPU, zwłaszcza gdy wewnętrzna pętla skanuje duże tabele.
  • Wielkość przestrzeni iteracji — jeżeli iterator przechodzi po tabeli o wysokiej kardynalności (np. wiele unikalnych wartości), FE wykona dużo pracy, nawet jeśli pojedyncza operacja jest prosta.

Nie chodzi o to, by unikać iteratorów zawsze — tylko by wiedzieć, kiedy są głównym kosztem i czy da się „zepchnąć” obliczenie do bardziej zestawowych operacji.

5.4. Spool/materializacja: co sygnalizuje i kiedy boli

Operator typu spool (lub analogiczny element buforowania) sugeruje, że silnik tworzy pośredni wynik, aby:

  • ponownie go wykorzystać w kolejnych krokach (cache),
  • obsłużyć złożone połączenia/filtry,
  • zmaterializować tabelę, której nie da się wygodnie przepuścić strumieniowo.

W praktyce spool jest istotny, gdy dotyczy dużych zbiorów lub powstaje wiele razy w tej samej ścieżce obliczeń. Wtedy plan często pokazuje, że FE nie może „przekazać dalej” prostych agregacji z SE, tylko musi budować struktury pośrednie w pamięci.

5.5. Łączenie wniosków z Query Plan z miarami (mapowanie przyczyn)

Największa wartość Query Plan pojawia się, gdy umiesz przetłumaczyć podejrzany operator na potencjalny problem w DAX. Poniższa tabela to szybka legenda diagnostyczna (bez wchodzenia w techniki optymalizacji):

Wzorzec w planie Co to zwykle oznacza w miarze Typowy skutek
Wiele poziomów iteratorów SUMX/FILTER lub inne iteracje na dużych tabelach; zagnieżdżone obliczenia per wiersz Wysoki CPU w FE, wrażliwość na kardynalność
Spool/materializacja pośrednich tabel Miara buduje/transformuje tabele w locie (np. rozbudowane warunki filtrów, dynamiczne zestawy) Duży narzut pamięci i CPU w FE, czas rośnie skokowo
Dużo operacji filtrowania/łączenia w gałęzi FE Złożony kontekst filtra, skomplikowane warunki, zależności od wielu tabel FE staje się „koordynatorem”, SE mniej efektywny
Proste skany/agregacje, mało FE Miara jest zestawowa, ale działa na dużym wolumenie danych Dominuje czas SE; problemem może być wolumen/kardynalność

5.6. Krótki przykład: jak plan naprowadza na fragment do poprawy

Poniżej celowo uproszczony przykład. Jeśli miara opiera się na iteracji po tabeli faktów:

Wynik :=
SUMX(
  'Fakt',
  'Fakt'[Kwota] * 'Fakt'[Wspolczynnik]
)

a w Query Plan widzisz podejrzanie „gęstą” gałąź z iteracją i ewentualnym buforowaniem, to sygnał diagnostyczny brzmi: koszt wynika z pracy per wiersz (a nie z samej agregacji). Kolejnym krokiem jest sprawdzenie, czy ta iteracja jest konieczna oraz jak duża jest przestrzeń iteracji w aktualnym kontekście zapytania.

5.7. Praktyczne zasady czytania planu (żeby się nie zgubić)

  • Najpierw identyfikuj „kształt” planu: czy dominuje praca FE (iteracje/spool), czy plan jest głównie skanami/agregacjami.
  • Nie poluj na pojedyncze słowo — jeden operator rzadko wyjaśnia wszystko; ważny jest kontekst gałęzi i to, co dzieje się „pod spodem”.
  • Łącz plan z kontekstem zapytania — ta sama miara może mieć inny plan w zależności od wizualizacji/filtrów; plan czytaj zawsze dla konkretnego scenariusza.
  • Używaj planu jako mapy do miary — celem nie jest „zrozumieć każdy node”, tylko znaleźć fragment logiki odpowiadający najcięższej ścieżce wykonania.
💡 Pro tip: Czytaj Query Plan od góry do dołu i najpierw oceń „kształt” gałęzi: zagnieżdżone iteratory oraz spool/materializacje to typowe źródła wysokiego FE Time, które potem mapujesz na konkretne fragmenty DAX (np. SUMX/FILTER, dynamiczne tabele). Zawsze zestawiaj podejrzane operatory z tym, co pokazał Server Timings (FE czy SE dominuje), bo plan mówi „dlaczego”, ale Timings potwierdzają „gdzie” faktycznie uciekł czas.

6. Typowe przyczyny wolnych miar

Wolna miara rzadko jest „z natury” wolna — zwykle staje się kosztowna w konkretnym kontekście zapytania: przy danym ziarnie wizualizacji, liczbie filtrów, relacjach w modelu i kształcie danych. Poniżej są najczęstsze źródła problemów, które warto rozpoznawać, zanim przejdziesz do szczegółowej analizy w Server Timings i Query Plan.

6.1. Kontekst filtra: drobne różnice, duże koszty

Ten sam DAX potrafi działać szybko na poziomie miesiąca, a dramatycznie wolno na poziomie pojedynczego produktu lub klienta. Wynika to z tego, że miara jest wykonywana wiele razy (dla wielu punktów siatki), a dodatkowo filtr może:

  • rozszerzać zakres danych (np. nieoczekiwanie usuwać filtr daty),
  • powodować kosztowne przejścia relacji (szczególnie przy filtrach z wielu tabel),
  • wymuszać pracę po stronie Formula Engine, gdy logika nie daje się łatwo „złożyć” do Storage Engine.

Typowy sygnał: miara ma akceptowalny czas całkowity na prostym wykresie, ale skaluje się źle na tabeli/macierzy z wieloma wymiarami.

6.2. Iteratory (funkcje z „X”): SUMX, AVERAGEX, FILTERX jako mnożnik pracy

Iteratory są potrzebne, gdy liczysz „po wierszach” (lub po grupach), ale ich koszt rośnie wraz z liczbą iterowanych elementów. Problemem nie jest sam SUMX, tylko sytuacja, gdy wewnątrz iteracji wykonujesz ciężkie wyrażenia (np. dodatkowe CALCULATE, skomplikowane warunki, odwołania do wielu tabel).

  • Wysokie cardinality w tabeli iterowanej = dużo kroków pętli.
  • Iteracja po tabeli faktów bywa znacznie droższa niż po małej tabeli wymiaru lub agregacji.
  • Zagnieżdżone iteratory potrafią eksplodować złożoność (pętla w pętli).

W praktyce warto traktować iteratory jako narzędzie precyzyjne: używać, gdy trzeba, ale świadomie ograniczać rozmiar tabeli wejściowej (np. przez agregację, filtr, wybór właściwej kolumny).

6.3. Złożone CALCULATE: przełączanie kontekstu i rozbudowane filtry

CALCULATE jest jednym z najpotężniejszych elementów DAX, ale potrafi generować koszt, gdy:

  • ma wiele argumentów filtrujących (szczególnie opartych o wyrażenia, a nie proste warunki kolumn),
  • używa konstrukcji typu FILTER(…) na dużych tabelach,
  • miesza w jednym miejscu modyfikacje relacji (np. aktywacja relacji, zmiana kierunku filtrowania) i warunki biznesowe.

Wysoki koszt często wynika nie z liczby linii kodu, tylko z tego, że filtr nie jest „prostym” filtrem kolumny, przez co silnik musi wykonać dodatkową pracę, zanim policzy agregację.

6.4. Relacje i propagacja filtrów: nieintuicyjne przejścia między tabelami

Relacje decydują, jak filtry przepływają przez model. Wolne miary często mają źródło w tym, że zapytanie musi przejść przez:

  • łańcuch relacji (kilka skoków między tabelami),
  • relacje oparte o kolumny o wysokiej kardynalności,
  • dwukierunkowe filtrowanie (używane bez potrzeby),
  • relacje nieaktywne aktywowane doraźnie w miarach.

Efekt uboczny: miara działa szybko przy filtrach z jednej tabeli, ale zwalnia po dodaniu filtra z innej części modelu (szczególnie przy wielu wymiarach naraz).

6.5. Cardinality i „kształt” danych: gdy wolumen nie jest jedynym problemem

Wydajność zależy nie tylko od liczby wierszy, ale też od liczby unikalnych wartości w kolumnach używanych do grupowania, filtrowania i relacji. Typowe pułapki:

  • klucze/identyfikatory i znaczniki czasu o bardzo wysokiej kardynalności wchodzą w relacje lub w oś wizualizacji,
  • kolumny tekstowe używane jako filtry zamiast zastąpienia ich kluczami/liczbami,
  • brak tabel agregujących (wszystko liczone z poziomu najdrobniejszego faktu).

Wysoka kardynalność często objawia się tym, że miara jest „ok” dla kilku wartości, ale gwałtownie degraduje się, gdy użytkownik wybiera bardziej szczegółowy poziom.

6.6. Nieoptymalne wzorce DAX: częste „antywzorce”

Poniższa tabela zbiera typowe sytuacje, które podnoszą koszt obliczeń i utrudniają silnikowi optymalizację:

Wzorzec Dlaczego bywa wolny Na co uważać
FILTER na dużej tabeli w miarze Buduje tabelę pośrednią i często przenosi pracę do Formula Engine Czy da się zastąpić prostym filtrem kolumny lub przygotować kolumnę pomocniczą
IF / SWITCH w iteracji Warunek wykonywany dla wielu elementów, często z kosztownymi gałęziami Minimalizować logikę per-wiersz, rozważyć wcześniejszą kategoryzację danych
Używanie miar w roli filtrów bez kontroli Miara może być liczona wielokrotnie podczas budowania filtra Sprawdzać, czy filtr nie powoduje wielokrotnych przeliczeń
COUNTROWS(FILTER(...)) zamiast prostszych konstrukcji FILTER materializuje tabelę logiczną i iteruje Szukaj prostszych predykatów i ograniczaj zakres danych
ALLEXCEPT / ALL na szerokich tabelach Resetowanie kontekstu może znacząco zwiększyć zakres skanowanych danych Upewnić się, że „usunięcie filtrów” jest naprawdę potrzebne

6.7. Krótki przykład „co boli” (tylko sygnał ostrzegawczy)

Poniższy fragment nie jest po to, aby pokazać kompletną optymalizację, tylko aby unaocznić typowy mechanizm: koszt rośnie, gdy filtrujemy dużą tabelę faktów w locie i robimy to w kontekście wielu punktów wizualizacji.

-- Potencjalnie kosztowne: FILTER na tabeli faktów wewnątrz miary
Wynik =
CALCULATE(
    SUM(Fact[Amount]),
    FILTER(Fact, Fact[Status] = "OK")
)

Jeśli taka miara jest użyta w macierzy z wieloma wymiarami, łatwo „wzmocnić” koszt przez liczbę wywołań. Dlatego w diagnostyce zawsze patrz na miarę razem z tym, w jakim kontekście jest wykonywana.

6.8. Lista kontrolna: co sprawdzić, gdy miara jest wolna

  • Czy miara nie skaluje się źle wraz ze wzrostem liczby komórek wizualizacji (kontekst zapytania)?
  • Czy używasz iteratorów nad dużą tabelą lub zagnieżdżonych iteratorów?
  • Czy CALCULATE nie zawiera kosztownych filtrów tabelarycznych (np. FILTER na fakcie)?
  • Czy relacje i kierunki filtrowania nie powodują niepotrzebnych przejść lub „rozlania” filtrów?
  • Czy kolumny w relacjach/grupowaniach nie mają bardzo wysokiej kardynalności?
  • Czy nie stosujesz wzorców, które utrudniają optymalizację (rozbudowane warunki w iteracji, resetowanie filtrów na szerokim zakresie)?

7. Przykłady krótkich fragmentów DAX: „wolny vs szybszy” oraz techniki ograniczania iteracji i redukcji pracy FE

Poniższe pary pokazują typowe sytuacje, w których miara staje się droga, bo Formula Engine musi wykonywać iteracje po wielu wierszach, budować duże tabele pośrednie albo wielokrotnie wywoływać ten sam fragment logiki w zmiennym kontekście. Celem nie jest „magiczne” przyspieszenie każdej miary, tylko zmniejszenie pracy FE i oddanie jak największej części obliczeń do Storage Engine lub do prostszych agregacji.

  • Iteratory (SUMX/AVERAGEX) vs agregacje kolumnowe: wolniej bywa wtedy, gdy iterujesz po dużej tabeli faktów tylko po to, by policzyć prostą sumę/średnią. Szybsze podejście to użycie funkcji agregujących, jeśli wynik da się uzyskać bez logiki „wiersz po wierszu”.
  • Filtruj przed iteracją: wolny wariant często iteruje po całej tabeli i dopiero wewnątrz sprawdza warunek. Szybszy wariant ogranicza zbiór na wejściu (mniejsza liczba wierszy do przejścia), np. przez zawężenie kontekstu filtra przed obliczeniem.
  • Unikaj liczenia tego samego wiele razy: miary „wolne” często powtarzają identyczne wyrażenie w kilku gałęziach logiki lub w wielu miejscach (np. w warunkach). Szybsze podejście to zapisanie wyniku w zmiennej i użycie go wielokrotnie, dzięki czemu FE nie musi powtarzać kosztownej części.
  • IF w iteracji vs warunek poza iteracją: gdy warunek jest stały dla bieżącego kontekstu (a nie dla każdego wiersza), jego sprawdzanie w środku iteratora jest zbędne. Lepszy wzorzec to ocenić warunek raz i dopiero potem wykonać jedną z dwóch prostszych ścieżek.
  • FILTER na dużych tabelach vs prostsze predykaty: koszt rośnie, gdy budujesz duże tabele pośrednie wyrażeniami filtrującymi, których nie da się łatwo „zepchnąć” do SE. Szybsza wersja zwykle opiera się o prostsze ograniczenia kontekstu (np. przez bezpośrednie filtry na kolumnach lub wykorzystanie istniejących relacji), zamiast składać rozbudowany FILTER.
  • Top N i sortowanie: wolno robi się, gdy miara wymusza sortowanie i rankingowanie dużego zbioru w każdej komórce wizualizacji. Szybciej jest ograniczyć zakres do niezbędnego minimum (mniej kandydatów do rankingu) i unikać niepotrzebnych operacji porządkujących w kontekście, gdzie nie są używane.
  • Miary zależne (measure-on-measure) i „łańcuszki”: wielowarstwowe zależności mogą powodować, że jedna komórka raportu uruchamia wiele zapytań cząstkowych. Szybszy wariant zwykle upraszcza logikę do krótszego łańcucha, łączy kroki lub eliminuje pośrednie miary tam, gdzie prowadzą do nadmiarowych obliczeń.
  • Praca na faktach vs praca na wymiarach: wolny wzorzec iteruje po tabeli faktów, mimo że logika dotyczy de facto unikalnych wartości wymiaru. Szybsze podejście przenosi iterację na mniejszy zbiór (np. listę kategorii/klientów), a dopiero potem agreguje fakty w kontekście tej listy.
  • ALL/REMOVEFILTERS używane „na ślepo”: zdejmowanie filtrów zbyt szeroko potrafi rozsadzić przestrzeń obliczeń i zwiększyć liczbę skanowanych wierszy. Szybszy wzorzec usuwa filtry tylko tam, gdzie to konieczne (konkretna kolumna/tabela), by nie powiększać kontekstu bardziej niż potrzeba.
  • Precyzyjne granice kontekstu w CALCULATE: wolno bywa, gdy w CALCULATE mieszają się niejasne filtry i złożone warunki, które generują ciężkie tabele pośrednie. Szybszy wariant trzyma filtry proste, możliwie selektywne i unika tworzenia dużych zbiorów „pomocniczych” w samym wyrażeniu.

Jeśli masz wrażenie, że miara „robi niewiele”, a mimo to jest droga, najczęściej oznacza to, że FE musi wykonać zbyt dużo pracy per komórka: za dużo iteracji, za duże tabele pośrednie albo za wiele powtórzeń tego samego wyrażenia w różnych kontekstach. Dobrym nawykiem jest zadawanie sobie trzech pytań: czy da się zredukować liczbę wierszy na wejściu, czy da się uniknąć iteratora, oraz czy da się policzyć część rzeczy raz (zmienne) zamiast wielokrotnie.

8. Lista szybkich optymalizacji do przetestowania: checklist + walidacja efektów w DAX Studio

Gdy miara „działa”, ale raport zaczyna się dławić, najszybciej zyskasz czas, wykonując serię krótkich, bezpiecznych testów. Poniższa lista to checklist rzeczy, które zwykle dają zauważalny efekt bez przebudowy całego modelu. Kluczem jest, aby każdą zmianę zweryfikować pomiarem w DAX Studio, zamiast polegać na wrażeniach z interfejsu raportu.

Checklist: szybkie optymalizacje, które warto sprawdzić

  • Ogranicz liczbę wywołań miar w jednej definicji: mniej zagnieżdżeń i mniej powtórzeń tego samego wyrażenia często zmniejsza koszt obliczeń.
  • Użyj zmiennych do przechowywania wyników pośrednich: szczególnie gdy to samo obliczenie jest wykorzystywane wielokrotnie w różnych gałęziach logiki.
  • Minimalizuj pracę w wierszu: jeśli miara „przechodzi” po wielu rekordach, spróbuj przesunąć logikę w stronę agregacji, a nie iteracji po elementach.
  • Zmniejsz liczbę filtrów i warunków wprowadzanych dynamicznie: każda dodatkowa manipulacja kontekstem może zwiększać koszt, zwłaszcza gdy filtr dotyka dużych tabel.
  • Uprość warunki logiczne: zbyt rozbudowane rozgałęzienia potrafią wielokrotnie wymuszać obliczenia pomocnicze; uproszczenie logiki bywa szybką wygraną.
  • Sprawdź, czy filtrujesz „w dobrą stronę”: kierunek filtracji (z tabel wymiarów do faktów) zwykle jest tańszy niż filtrowanie faktów i „ciągnięcie” kontekstu w górę.
  • Ogranicz zakres kontekstu: jeżeli wizual pokazuje zbyt drobne poziomy szczegółowości, rozważ zawężenie (mniej kategorii, krótszy zakres dat), bo miara jest liczona dla każdej komórki siatki.
  • Eliminuj zbędne przejścia między tabelami: zbyt długie ścieżki relacji i niejednoznaczne połączenia często windują koszt filtrowania i propagacji kontekstu.
  • Zredukuj kardynalność w modelu tam, gdzie to możliwe: kolumny o wysokiej unikalności w filtrach i grupowaniach potrafią istotnie pogorszyć wydajność.
  • Unikaj pracy na szerokich, „ciężkich” kolumnach w filtrach: wybieraj klucze/liczby zamiast tekstów, gdy to możliwe, bo to zwykle przekłada się na tańsze filtrowanie.
  • Zweryfikuj, czy problem nie leży w wizualu: czasem miara jest w porządku, a koszt generuje liczba punktów danych, tooltipy, sortowania lub wiele warstw interakcji.
  • Sprawdź, czy da się przenieść część logiki do modelu: prosta kolumna kalkulowana lub przygotowanie danych w Power Query potrafi odjąć pracy w czasie zapytania (kosztem odświeżania).
  • Rozważ uproszczenie modelu: mniej kolumn, mniej nieużywanych tabel, mniej relacji — to często „małe sprzątanie”, które poprawia wszystko naraz.

Walidacja w DAX Studio: jak mierzyć efekt, żeby nie oszukały Cię przypadki

  • Testuj porównawczo: zmierz „przed” i „po” dla tego samego scenariusza (te same filtry, ten sam kontekst, ten sam zakres danych).
  • Powtarzaj pomiar: wykonaj kilka uruchomień i porównuj trend, nie pojedynczy wynik. Pojedynczy strzał może być zaburzony przez cache, inne procesy i losowe wahania.
  • Oddziel wpływ cache od realnej poprawy: patrz, czy zmiana poprawia zarówno pierwsze wykonanie (zimniej), jak i kolejne (cieplej). Jeżeli zysk widać tylko „po rozgrzaniu”, optymalizacja może być pozorna.
  • Porównuj metryki, nie tylko czas: obserwuj równolegle czas całkowity, CPU oraz liczbę/ciężar zapytań do Storage Engine. Zmiana może skrócić Duration, ale podnieść CPU albo odwrotnie.
  • Zwracaj uwagę na rozkład kosztu: jeśli po zmianie spada koszt po stronie Storage Engine, a rośnie po stronie Formula Engine (lub odwrotnie), to sygnał, że optymalizacja przesunęła pracę zamiast ją ograniczyć.
  • Kontroluj kontekst zapytania: porównuj wyniki dla tego samego wizualu/układu, bo inny poziom szczegółu może całkowicie zmienić profil kosztów.
  • Notuj wnioski: zapisuj, co zmieniłeś i jaki był efekt w metrykach; po kilku próbach łatwo wrócić do najlepszej wersji i uniknąć „optymalizacji w ciemno”.

Najważniejsza zasada tej checklisty: optymalizuj iteracyjnie i mierz. Nawet drobna korekta potrafi dać wyraźny zysk, ale tylko DAX Studio pozwoli Ci jednoznacznie potwierdzić, czy faktycznie odciążyłeś silnik, a nie tylko zmieniłeś warunki testu.

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 DAX query plan w praktyce: jak czytać Server Timings i wyłapać najdroższe miary

Kiedy analiza Server Timings w DAX Studio ma największy sens?

Analiza Server Timings ma największy sens wtedy, gdy raport zwalnia tylko w konkretnym kontekście. Dotyczy to sytuacji, w których wizualizacje długo się odświeżają, miara spowalnia cały widok albo problem pojawia się dopiero po drill-downie, zmianie osi lub określonej kombinacji filtrów. Dzięki temu diagnozujesz realny koszt zapytania, a nie sam zapis formuły.

Jak odróżnić w DAX Studio problem po stronie Formula Engine od problemu po stronie Storage Engine?

Najprościej odróżnisz to po relacji FE Time do SE Time. Jeśli dominuje FE Time, problem zwykle leży w logice miary, iteracjach lub kosztownych tabelach pośrednich. Jeśli dominuje SE Time, częściej chodzi o skany danych, agregacje, relacje albo mało selektywne filtry. Gdy oba czasy są wysokie, zapytanie bywa ciężkie jednocześnie dla warstwy obliczeniowej i danych.

Jak znaleźć najdroższą miarę, jeśli jeden visual używa kilku miar naraz?

Najskuteczniej znajdziesz ją metodą porównawczą A/B. Uruchom visual lub zapytanie z jedną miarą, a potem dodawaj kolejne pojedynczo i obserwuj, która powoduje największy skok czasu. Patrz przede wszystkim na:

  • przyrost FE Time,
  • przyrost SE Time,
  • wzrost liczby SE Queries,
  • zmianę liczby Rows.

Taka izolacja zwykle szybciej wskazuje winowajcę niż analiza całego visuala naraz.

Co oznacza duża liczba SE Queries w Server Timings?

Duża liczba SE Queries często oznacza, że Formula Engine wielokrotnie odpytuje Storage Engine. W praktyce bywa to sygnał iteracji, w której silnik wykonuje wiele małych zapytań zamiast jednego bardziej zestawowego obliczenia. Sama liczba SE Queries nie jest jeszcze błędem, ale jej nagły wzrost wraz z FE Time i Duration zwykle wskazuje na kosztowny wzorzec wykonania.

Na co patrzeć najpierw w Query Plan, żeby nie zgubić się w planie wykonania DAX?

Najpierw patrz na ogólny kształt planu, a nie na każdy pojedynczy operator. Najważniejsze jest ustalenie, czy plan pokazuje głównie prostą pracę na danych, czy raczej rozbudowaną ścieżkę FE. Na start skup się na trzech elementach:

  • czy widać iteratory,
  • czy pojawia się spool lub materializacja,
  • czy gałąź wygląda na FE-heavy czy SE-heavy.

Dopiero potem mapuj te obserwacje do fragmentów miary.

Dlaczego ta sama miara może działać szybko na karcie, a wolno w tabeli lub macierzy?

Ta sama miara może być wolna w tabeli, bo jest liczona wielokrotnie dla wielu grup i filtrów jednocześnie. Na karcie zwykle liczysz jedną wartość w prostym kontekście. W tabeli, macierzy lub drill-downie ta sama logika wykonuje się dla wielu komórek, co zwiększa liczbę obliczeń, iteracji i zapytań do silnika danych.

Jakie wzorce DAX najczęściej prowadzą do wolnych miar?

Najczęściej spowalniają miary iteratory, złożone CALCULATE i filtrowanie dużych tabel w locie. Szczególnie podejrzane są sytuacje, w których koszt rośnie wraz ze szczegółowością visuala. Częste źródła problemów to:

  • SUMX lub inne iteratory nad dużą tabelą,
  • FILTER na tabeli faktów wewnątrz miary,
  • rozbudowane warunki IF lub SWITCH w iteracji,
  • szerokie użycie ALL lub ALLEXCEPT.

Jak sprawdzić, czy optymalizacja miary naprawdę zadziałała?

Optymalizacja zadziałała wtedy, gdy poprawa jest widoczna w porównywalnych pomiarach, a nie tylko w pojedynczym uruchomieniu. Porównuj ten sam scenariusz przed i po zmianie, przy tych samych filtrach i podobnym kontekście. Oceniaj nie tylko Duration, ale też CPU, FE Time, SE Time oraz liczbę SE Queries, żeby upewnić się, że koszt rzeczywiście spadł, a nie tylko przesunął się między silnikami.

icon

Formularz kontaktowyContact form

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