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 یک مسئله چندلایه است
۴۵.۲. قانون اول؛ قبل از Optimization اندازه بگیر
بدون Baseline ممکن است دو ساعت روی DAX کار کنی در حالی که مشکل اصلی SQL Source یا یک Visual سفارشی است.
۴۵.۳. Baseline
| Metric | نمونه |
|---|---|
| Page load | 4.8 sec |
| Visual query | 1.7 sec |
| Model size | 850 MB |
| Refresh | 22 min |
| Rows | 80M |
۴۵.۴. 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 مثال
| Column | Cardinality |
|---|---|
| Region | 10 |
| Product Category | 40 |
| Customer | 500K |
| Transaction GUID | 80M |
| Timestamp ms | 75M |
۴۵.۱۸. 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 Fact | Aggregation |
|---|---|
| Transaction | Month+Region |
| 80M rows | 20K rows |
| Detail analysis | Executive KPI |
| Heavy scan | Fast 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
۴۵.۷۶. یک تغییر در هر مرحله
اگر همزمان Model، DAX و Visual را عوض کنی، نمیفهمی کدام تغییر واقعاً مؤثر بوده است.
۴۵.۷۷. Before/After
| Metric | Before | After |
|---|---|---|
| Page load | 8.2s | 2.9s |
| Model size | 1.4GB | 720MB |
| Refresh | 48m | 17m |
۴۵.۷۸. 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
| لایه | سؤال |
|---|---|
| Source | Query سریع است؟ |
| Power Query | Folding دارد؟ |
| Model | Column اضافه؟ Cardinality؟ |
| Relationship | ساده است؟ |
| DAX | FE/SE bottleneck؟ |
| Visual | تعداد/Rendering؟ |
| Service | Capacity/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
| خروجی | شرح |
|---|---|
| Baseline | Load/size/refresh |
| Analyzer | Visual bottlenecks |
| VertiPaq Review | Cardinality/size |
| DAX Profile | Server timings |
| Model Cleanup | Columns/relationships |
| Visual Cleanup | Query reduction |
| Scale Strategy | Incremental/aggregation |
| Benchmark | Before/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.