فصل 45 از 50 درس 1 از 1

Session 45 — Performance Optimization حرفه‌ای در Power BI؛ DAX، VertiPaq، Model و Visual

Performance Optimization حرفه‌ای در Power BI؛ DAX، VertiPaq، Model و Visual

بخشی از آموزش جامع Power BI

محتوای درس Performance Optimization حرفه‌ای در Power BI؛ DAX، VertiPaq، Model و Visual

شروع جلسه؛ چرا بعضی Dashboardها سریع‌اند و بعضی آدم را پیر می‌کنند؟

ممکن است دو Report دقیقاً یک خروجی نشان بدهند، ولی یکی در یک ثانیه باز شود و دیگری ده ثانیه طول بکشد. فرق معمولاً فقط سخت‌افزار نیست؛ مدل داده، Cardinality، DAX، تعداد Visualها، Power Query و Source همگی روی Performance اثر دارند.

در این فصل یاد می‌گیریم به جای حدس زدن، اول گلوگاه را اندازه بگیریم و بعد همان بخش را بهینه کنیم.

۴۵.۱. Performance یک مسئله چندلایه است

شکل ۴۵-۱ — کندی می‌تواند از Source تا Visual و تجربه کاربر در هر لایه‌ای ایجاد شود
شکل ۴۵-۱ — کندی می‌تواند از Source تا Visual و تجربه کاربر در هر لایه‌ای ایجاد شود

۴۵.۲. قانون اول؛ قبل از Optimization اندازه بگیر

بدون Baseline ممکن است دو ساعت روی DAX کار کنی در حالی که مشکل اصلی SQL Source یا یک Visual سفارشی است.

۴۵.۳. Baseline

Metricنمونه
Page load4.8 sec
Visual query1.7 sec
Model size850 MB
Refresh22 min
Rows80M

۴۵.۴. Performance Analyzer

Performance Analyzer داخل Power BI Desktop کمک می‌کند زمان مربوط به DAX Query، Visual Display و بخش‌های دیگر را برای Visualهای صفحه ببینی.

۴۵.۵. روش استفاده

Recording را شروع کن، Visualها را Refresh کن و Visualهای کند را بر اساس زمان واقعی پیدا کن.

۴۵.۶. Copy Query

برای Visualهای مسئله‌دار می‌توان Query تولیدشده را بررسی و در ابزارهای تخصصی‌تر تحلیل کرد.

۴۵.۷. Visual Display کند

اگر DAX سریع است ولی Visual Display سنگین است، مشکل ممکن است تعداد Data Point، Custom Visual یا Formatting پیچیده باشد.

۴۵.۸. DAX Query کند

اگر بخش Query زمان زیادی می‌گیرد، Measure، Filter Context و Model را بررسی کن.

۴۵.۹. DAX Studio

DAX Studio یکی از ابزارهای مهم برای تحلیل Query، Server Timings، Query Plan و رفتار Storage/Formula Engine است.

۴۵.۱۰. Server Timings

با Server Timings می‌توان دید زمان Query بیشتر در Storage Engine مصرف شده یا Formula Engine.

۴۵.۱۱. Storage Engine

VertiPaq/Storage Engine در عملیات ستونی و Aggregationهای مناسب بسیار سریع است.

۴۵.۱۲. Formula Engine

منطق پیچیده DAX، Iterationها و بعضی عملیات می‌توانند کار بیشتری به Formula Engine بدهند.

۴۵.۱۳. هدف چیست؟

هدف این نیست که Formula Engine صفر شود؛ هدف این است که منطق بی‌دلیل سنگین نداشته باشیم و Engineها را آگاهانه استفاده کنیم.

۴۵.۱۴. VertiPaq چیست؟

VertiPaq موتور ستونی و فشرده‌سازی مدل Import است. طراحی Columnها مستقیماً روی حجم و سرعت آن اثر دارد.

۴۵.۱۵. Columnar Storage

داده به شکل Column-oriented ذخیره می‌شود؛ بنابراین نوع داده، تعداد مقادیر یکتا و قابلیت فشرده‌سازی مهم‌اند.

۴۵.۱۶. Cardinality

Cardinality یعنی تعداد مقادیر متمایز یک Column. Column با میلیون‌ها مقدار یکتا معمولاً فشرده‌سازی سخت‌تری نسبت به Region با ۱۰ مقدار دارد.

۴۵.۱۷. High-cardinality مثال

ColumnCardinality
Region10
Product Category40
Customer500K
Transaction GUID80M
Timestamp ms75M

۴۵.۱۸. GUID

GUIDهای یکتا در Fact بزرگ می‌توانند حجم زیادی مصرف کنند. اگر برای تحلیل لازم نیستند، حذفشان را بررسی کن.

۴۵.۱۹. Text Columns

Textهای طولانی در Fact بزرگ می‌توانند مدل را سنگین کنند. Description و Comment تراکنش را فقط در صورت نیاز تحلیلی وارد مدل کن.

۴۵.۲۰. Integer Keys

برای Relationshipها معمولاً Integer surrogate keys از Text Keyهای طولانی مناسب‌ترند.

۴۵.۲۱. DateTime Cardinality

اگر DateTime تا ثانیه یا میلی‌ثانیه داری ولی تحلیل فقط روزانه است، Split یا کاهش Grain می‌تواند Cardinality را کم کند.

۴۵.۲۲. حذف Columnهای اضافی

یکی از ساده‌ترین Optimizationها این است: چیزی را که Report استفاده نمی‌کند وارد Model نکن.

۴۵.۲۳. VertiPaq Analyzer

با ابزارهای تحلیل مدل می‌توان اندازه Table/Column، Cardinality و سهم هر Column از Memory را بررسی کرد.

۴۵.۲۴. مدل باریک

Fact Table باید تا حد امکان باریک باشد؛ Keyها و Measure-supporting columns لازم را نگه دار.

۴۵.۲۵. Star Schema

Star Schema فقط برای فهم مدل خوب نیست؛ معمولاً Query Pattern و Relationshipها را هم ساده‌تر می‌کند.

۴۵.۲۶. Flat Table بزرگ

یک Table بسیار پهن با تکرار RegionName، CategoryName و Customer attributes در میلیون‌ها Row معمولاً انتخاب خوبی نیست.

۴۵.۲۷. Dimension

Attributeهای توصیفی را به Dimension مناسب منتقل کن تا Fact تکرار بی‌دلیل نداشته باشد.

۴۵.۲۸. Relationship

Relationshipهای غیرضروری، Many-to-Many و Bidirectional را فقط وقتی نیاز واقعی داری استفاده کن.

۴۵.۲۹. Bidirectional

Filter دوطرفه می‌تواند Context و Query Plan را پیچیده کند. Single-direction را Default ذهنی قرار بده مگر Business نیاز دیگری داشته باشد.

۴۵.۳۰. Many-to-Many

Many-to-Many گاهی لازم است ولی باید Grain و Bridge روشن باشد؛ استفاده تصادفی می‌تواند هم Performance و هم Correctness را خراب کند.

۴۵.۳۱. Auto Date/Time

در مدل حرفه‌ای بزرگ معمولاً Date Table کنترل‌شده بهتر از ایجاد Date Tableهای پنهان متعدد است.

۴۵.۳۲. Calculated Column vs Measure

Calculated Column در Refresh محاسبه و ذخیره می‌شود؛ Measure هنگام Query محاسبه می‌شود. انتخاب اشتباه می‌تواند حجم یا Query Cost را زیاد کند.

۴۵.۳۳. چیزی که Dimension است Measure نکن

اگر Classification ثابت در Refresh قابل محاسبه است، شاید Column/ETL مناسب باشد؛ اگر Context-dependent است Measure لازم است.

۴۵.۳۴. DAX Variables

Profit % =
VAR SalesAmount = [Total Sales]
VAR ProfitAmount = [Profit]
RETURN
DIVIDE(ProfitAmount, SalesAmount)

۴۵.۳۵. VAR فقط برای سرعت نیست

Variable خوانایی و جلوگیری از تکرار Expression را بهتر می‌کند؛ گاهی Engine هم می‌تواند از محاسبه تکراری جلوگیری کند.

۴۵.۳۶. FILTER روی Table بزرگ

FILTER می‌تواند لازم باشد، ولی روی Fact بسیار بزرگ و Expression پیچیده باید با Server Timings تست شود.

۴۵.۳۷. Filter ساده

Sales Active =
CALCULATE(
    [Total Sales],
    DimProduct[IsActive] = TRUE()
)

۴۵.۳۸. Filter Context را روی Dimension اعمال کن

اگر Business Rule روی Product Category است، معمولاً Filter کردن Dimension مناسب‌تر از پیمایش بی‌دلیل Fact است.

۴۵.۳۹. SUMX

Iteratorهایی مثل SUMX ابزارهای قدرتمندی هستند، ولی Iteration روی میلیون‌ها Row با Expression پیچیده هزینه دارد.

۴۵.۴۰. SUM vs SUMX

-- ساده
Total Sales = SUM(FactSales[SalesAmount])

-- وقتی Row expression واقعاً لازم است
Revenue = SUMX(FactSales, FactSales[Qty] * FactSales[UnitPrice])

۴۵.۴۱. Precompute

اگر Qty * UnitPrice همیشه یک منطق ثابت و پرمصرف است، بسته به معماری ممکن است محاسبه آن در Source/ETL ارزش بررسی داشته باشد.

۴۵.۴۲. DISTINCTCOUNT

DISTINCTCOUNT روی Column با Cardinality بالا می‌تواند سنگین‌تر از SUM ساده باشد. آن را حذف نکن، ولی انتظار Cost متفاوت داشته باش.

۴۵.۴۳. DISTINCTCOUNT Customer

اگر KPI واقعی Active Customers است، DISTINCTCOUNT لازم است؛ Optimization نباید معنی Business را قربانی کند.

۴۵.۴۴. IF و Branching

Measureهای بزرگ با SWITCH/IFهای تو در تو را Profile کن. Dynamic Reports می‌توانند فقط Branch انتخابی را خوب طراحی کنند ولی باید اندازه‌گیری شوند.

۴۵.۴۵. DIVIDE

برای تقسیم Measureها DIVIDE معمولاً خواناتر و برای مدیریت صفر مناسب است.

۴۵.۴۶. CALCULATE

CALCULATE قلب DAX است؛ تعداد زیاد CALCULATE لزوماً بد نیست. مسئله Filter Expression و Context Transition است.

۴۵.۴۷. Context Transition

وقتی CALCULATE در Row Context استفاده می‌شود، Context Transition رخ می‌دهد. در Iteratorهای بزرگ این موضوع را بفهم و تست کن.

۴۵.۴۸. Measure Branching

Measureهای پایه مثل Sales، Cost و Profit بساز و KPIهای پیچیده را روی آن‌ها Branch کن؛ این کار نگهداری و Optimization را ساده‌تر می‌کند.

۴۵.۴۹. Base Measures

Total Sales = SUM(FactSales[SalesAmount])
Total Cost = SUM(FactSales[CostAmount])
Profit = [Total Sales] - [Total Cost]
Margin % = DIVIDE([Profit], [Total Sales])

۴۵.۵۰. Measure Explosion

صدها Measure بدون Folder، Naming و Usage Review باعث پیچیدگی می‌شوند. Measureهای مرده را پاکسازی کن.

۴۵.۵۱. Visual Count

هر Visual می‌تواند Query خودش را داشته باشد. صفحه ۳۰ Visualه معمولاً هم UX و هم Performance ضعیف‌تری دارد.

۴۵.۵۲. Visual Interactions

کلیک روی یک Visual ممکن است چندین Visual دیگر را دوباره Query کند. Edit Interactions را با Performance در نظر بگیر.

۴۵.۵۳. Slicer Cardinality

Slicer با میلیون‌ها Customer Name تجربه خوبی نیست. Search، Hierarchy یا مسیر انتخاب محدودتر طراحی کن.

۴۵.۵۴. Table Visual

نمایش هزاران Row در Table/Matrix هم Query و هم Rendering را سنگین می‌کند. Detail را Progressive Disclosure کن.

۴۵.۵۵. Top N

برای Executive Page معمولاً Top 10/20 مفیدتر از نمایش تمام Customerهاست.

۴۵.۵۶. Custom Visual

Custom Visualها را جدا Profile کن. بعضی‌ها Rendering یا Query Behavior متفاوتی دارند.

۴۵.۵۷. Tooltip

Report Page Tooltip هم Query اجرا می‌کند؛ آن را با Measureهای سنگین پر نکن.

۴۵.۵۸. Hidden Visual

مخفی کردن Visual در Bookmark همیشه به معنی حذف کامل هزینه معماری نیست؛ رفتار واقعی را با Analyzer تست کن.

۴۵.۵۹. Query Reduction

برای DirectQuery، گزینه‌های Query Reduction و رفتار Slicer/Filter می‌توانند تعداد Queryهای Source را کاهش دهند.

۴۵.۶۰. DirectQuery Performance

در DirectQuery، Index، SQL Query، Network latency و Source concurrency اهمیت بسیار بیشتری پیدا می‌کنند.

۴۵.۶۱. SQL Source

اگر Query Source کند است، Power BI نمی‌تواند همه مشکلات Database را جادو کند. Execution Plan و Indexها را با DBA بررسی کن.

۴۵.۶۲. Power Query

Transformationهای سنگین را Profile کن و Query Folding را تا حد امکان حفظ کن.

۴۵.۶۳. Early Filter

اگر فقط سه سال داده لازم داری، Filter را زود اعمال کن تا Source Rowهای غیرضروری را ارسال نکند.

۴۵.۶۴. Remove Columns Early

Columnهای غیرضروری را زود حذف کن تا حجم انتقال و پردازش کمتر شود.

۴۵.۶۵. Merge

Mergeهای متعدد روی Data بزرگ می‌توانند سنگین شوند؛ Folding و Source-side Join را بررسی کن.

۴۵.۶۶. Refresh Performance

Query Performance و Refresh Performance دو مسئله مرتبط ولی متفاوت‌اند. ممکن است Report سریع باشد ولی Refresh یک ساعت طول بکشد.

۴۵.۶۷. Incremental Refresh

برای Fact بزرگ، Incremental Refresh جلسه قبل می‌تواند Refresh Window را به‌شدت کاهش دهد.

۴۵.۶۸. Aggregation

برای مدل‌های بسیار بزرگ، Aggregation Table می‌تواند Queryهای سطح بالا را بدون Scan کردن Detail Fact پاسخ دهد.

۴۵.۶۹. Aggregation Concept

Detail FactAggregation
TransactionMonth+Region
80M rows20K rows
Detail analysisExecutive KPI
Heavy scanFast summary

۴۵.۷۰. Composite Model

در معماری‌های بزرگ می‌توان Import Aggregation و DirectQuery Detail را ترکیب کرد؛ این طراحی نیاز به تست و Governance دقیق دارد.

۴۵.۷۱. Model Size Budget

برای Model یک Budget ذهنی داشته باش و رشد ماهانه حجم را مانیتور کن.

۴۵.۷۲. Growth

مدلی که امروز 500MB است و ماهانه 20% رشد می‌کند، مسئله آینده را از همین امروز نشان می‌دهد.

۴۵.۷۳. Performance Budget

نوعهدف نمونه
Executive page< 3 sec
Drill page< 5 sec
Tooltipتقریباً فوری
Refreshداخل SLA

۴۵.۷۴. اعداد بالا قانون جهانی نیستند

Performance Target باید با زیرساخت، Capacity، حجم داده و انتظار کاربران تعریف شود؛ مهم این است که Target داشته باشی.

۴۵.۷۵. Optimization Workflow

شکل ۴۵-۲ — Baseline بگیر، گلوگاه را پیدا کن، یک تغییر بده و دوباره اندازه‌گیری کن
شکل ۴۵-۲ — Baseline بگیر، گلوگاه را پیدا کن، یک تغییر بده و دوباره اندازه‌گیری کن

۴۵.۷۶. یک تغییر در هر مرحله

اگر همزمان Model، DAX و Visual را عوض کنی، نمی‌فهمی کدام تغییر واقعاً مؤثر بوده است.

۴۵.۷۷. Before/After

MetricBeforeAfter
Page load8.2s2.9s
Model size1.4GB720MB
Refresh48m17m

۴۵.۷۸. Cache

تست Performance را با درک Cache انجام بده. اجرای دوم Query ممکن است به دلیل Cache سریع‌تر باشد.

۴۵.۷۹. Cold vs Warm

برای Benchmark جدی، شرایط تست را ثبت کن: Cold/Warm cache، فیلترها، Page و User Role.

۴۵.۸۰. RLS Performance

Dynamic RLS می‌تواند Query Pattern را تغییر دهد. Report را با Roleهای واقعی هم Profile کن.

۴۵.۸۱. Dynamic Parameter Performance

هر KPI در Field Parameter ممکن است Cost متفاوت داشته باشد؛ همه Selectionهای مهم را تست کن.

۴۵.۸۲. Mobile

صفحه موبایل با Visualهای کمتر می‌تواند تجربه بهتری بدهد، ولی Performance آن را روی شرایط واقعی Network هم بررسی کن.

۴۵.۸۳. پروژه شرکت هانا؛ مشکل

فرض کن Executive Page شامل ۱۸ Visual، FactSales با ۸۰ میلیون Row و Model حدود ۱.۴GB است و Page هشت ثانیه Load می‌شود.

۴۵.۸۴. پروژه؛ مرحله اول

Performance Analyzer را اجرا کن و سه Visual کند را پیدا کن. قبل از تغییر، زمان‌ها را ثبت کن.

۴۵.۸۵. پروژه؛ مرحله دوم

VertiPaq Analyzer را بررسی کن؛ GUID، Transaction Description و Timestamp با Cardinality بالا را شناسایی کن.

۴۵.۸۶. پروژه؛ مرحله سوم

Columnهای غیرضروری را حذف و Fact را باریک کن. Relationshipهای اضافی و Bidirectional را Review کن.

۴۵.۸۷. پروژه؛ مرحله چهارم

Measureهای کند را در DAX Studio با Server Timings بررسی کن و Iterationهای پرهزینه را پیدا کن.

۴۵.۸۸. پروژه؛ مرحله پنجم

Visualهای کم‌ارزش را حذف یا به Drill Page منتقل کن و Executive Page را Summary نگه دار.

۴۵.۸۹. پروژه؛ مرحله ششم

نتیجه Before/After را مستند کن؛ اگر بهبود واقعی نبود تغییر را کورکورانه نگه ندار.

۴۵.۹۰. Performance Checklist

لایهسؤال
SourceQuery سریع است؟
Power QueryFolding دارد؟
ModelColumn اضافه؟ Cardinality؟
Relationshipساده است؟
DAXFE/SE bottleneck؟
Visualتعداد/Rendering؟
ServiceCapacity/Network؟

۴۵.۹۱. خطای رایج؛ Optimization بدون Measurement

فقط چون یک DAX کوتاه‌تر شد، الزاماً سریع‌تر نشده است.

۴۵.۹۲. خطای رایج؛ حذف منطق Business

Performance بهتر با KPI اشتباه هیچ ارزشی ندارد. Correctness اولویت دارد.

۴۵.۹۳. خطای رایج؛ همه چیز در Fact

Text و Attributeهای تکراری Model را بزرگ می‌کنند.

۴۵.۹۴. خطای رایج؛ ۳۰ Visual

همزمان UX، Query Count و Rendering را خراب می‌کند.

۴۵.۹۵. خطای رایج؛ DirectQuery بدون DBA

Source کند است ولی تیم فقط Power BI را دستکاری می‌کند.

۴۵.۹۶. خطای رایج؛ Performance فقط Desktop

Service، Capacity، RLS و Network هم باید در محیط واقعی تست شوند.

۴۵.۹۷. Best Practiceها

اول Baseline بگیر.

Performance Analyzer را از Visual شروع کن.

DAX Studio را برای Queryهای کند استفاده کن.

Model را باریک نگه دار.

High-cardinality Columnها را Review کن.

Star Schema بساز.

Relationshipهای پیچیده را محدود کن.

Power Query Folding را حفظ کن.

Visualهای کم‌ارزش را حذف کن.

Incremental/Aggregation را برای حجم بالا بررسی کن.

هر Optimization را Before/After اندازه بگیر.

Performance Budget تعریف کن.

۴۵.۹۸. تمرین ۱

یک صفحه Report را با Performance Analyzer اندازه بگیر و سه Visual کند را ثبت کن.

۴۵.۹۹. تمرین ۲

پنج Column با Cardinality بالا در Model پیدا کن و تصمیم نگهداری/حذف آن‌ها را توضیح بده.

۴۵.۱۰۰. تمرین ۳

یک Measure سنگین را در DAX Studio تحلیل کن و Server Timings آن را قبل و بعد مقایسه کن.

۴۵.۱۰۱. تمرین ۴

یک Flat Fact را به Star Schema مفهومی تبدیل کن.

۴۵.۱۰۲. تمرین ۵

یک صفحه ۱۵ Visualه را به Executive Page حداکثر ۸ Visual اصلی بازطراحی کن.

۴۵.۱۰۳. تمرین چالشی

برای Fact 100M Row، معماری Performance شامل Incremental Refresh، Aggregation، Star Schema و Performance Budget طراحی کن.

۴۵.۱۰۴. پروژه Session؛ Performance Optimization Pack

خروجیشرح
BaselineLoad/size/refresh
AnalyzerVisual bottlenecks
VertiPaq ReviewCardinality/size
DAX ProfileServer timings
Model CleanupColumns/relationships
Visual CleanupQuery reduction
Scale StrategyIncremental/aggregation
BenchmarkBefore/after

هدف پروژه این است که Optimization از یک کار سلیقه‌ای به فرآیند مهندسی قابل اندازه‌گیری تبدیل شود.

جمع‌بندی Session 45

گزارش سریع نتیجه یک فرمول جادویی نیست؛ نتیجه هماهنگی Source، Model، DAX و UI است. حرفه‌ای‌ها اول اندازه می‌گیرند، بعد گلوگاه واقعی را اصلاح می‌کنند.

Measure → Locate bottleneck → Optimize the right layer → Retest → Keep only proven improvements

Session 46: Deployment Pipelines، ALM، Dev/Test/Prod، Source Control، PBIP و مدیریت حرفه‌ای نسخه و انتشار Power BI.