DAX FILTER, FILTER function DAX, تابع FILTER در DAX, تابع FILTER پاور BI, FILTER در Power BI, فیلتر جدول در DAX, فیلتر کردن جدول در Power BI, DAX Table Expression, DAX Table Functions, Virtual Table DAX, FILTER vs CALCULATE DAX, FILTER vs CALCULATETABLE, CALCULATETABLE DAX, DAX Filter Context, Boolean Filter Expression DAX, Formula Engine DAX, Storage Engine DAX, Power BI Performance, DAX Performance, KEEPFILTERS DAX, بهینه سازی DAX, بهینه سازی FILTER, Performance در Power BI, توابع جدول در DAX, فیلتر در Power BI, آموزش DAX, آموزش Power BI

در میان توابع DAX، شاید هیچ تابعی به‌اندازه FILTER در نگاه اول ساده و در عمل پرکاربرد و پیچیده نباشد. تقریباً هر توسعه‌دهنده Power BI در همان روزهای اول یادگیری با این تابع آشنا می‌شود، اما درک عمیق آن، به‌خصوص تفاوتش با فیلتر بولی مستقیم داخل CALCULATE و تأثیر آن بر Performance مدل، معمولاً سال‌ها طول می‌کشد تا در تجربه یک توسعه‌دهنده جا بیفتد.

FILTER برخلاف بسیاری از توابع DAX که یک مقدار Aggregate برمی‌گردانند، خروجی‌اش یک جدول است، نه یک عدد یا متن. این ویژگی FILTER را به یکی از ابزارهای اصلی برای ساخت جدول‌های مجازی در DAX تبدیل کرده است؛ Expressionهای جدولی که در زمان ارزیابی محاسبه ایجاد می‌شوند و لزوماً به‌عنوان یک جدول فیزیکی مستقل در مدل ذخیره نمی‌شوند، و پایه بسیاری از محاسبات پیشرفته، از رتبه‌بندی گرفته تا تحلیل‌های شرطی چندلایه، هستند.

در این مقاله بررسی می‌کنیم FILTER دقیقاً چه کاری انجام می‌دهد، چه تفاوتی با فیلتر مستقیم داخل CALCULATE دارد، چگونه با سایر توابع مانند CALCULATETABLE، ALL و KEEPFILTERS ترکیب می‌شود، چه زمانی استفاده از آن مناسب است و چه نکاتی از منظر Performance در مدل‌های سازمانی حجیم باید رعایت شود.

تعریف FILTER و ماهیت خروجی آن

FILTER تابعی است که یک جدول را به‌عنوان ورودی می‌گیرد، برای هر ردیف آن یک شرط منطقی را ارزیابی می‌کند و در نهایت جدولی جدید بازمی‌گرداند که تنها شامل ردیف‌هایی است که آن شرط را برآورده می‌کنند. ساختار کلی این تابع به شکل زیر است.

FILTER ( <Table>, <Condition> )

پارامتر اول جدولی است که باید فیلتر شود و می‌تواند یک جدول فیزیکی موجود در مدل یا یک جدول مجازی تولیدشده توسط تابع دیگری باشد. پارامتر دوم یک Boolean Expression است که برای تعیین اینکه هر ردیف جدول ورودی باید در نتیجه نهایی باقی بماند یا خیر، ارزیابی می‌شود.

نکته کلیدی که باید در ابتدا روشن شود این است که FILTER، برخلاف SUM یا COUNT، یک مقدار Scalar تولید نمی‌کند. خروجی آن همیشه یک جدول است و به همین دلیل، FILTER به‌تنهایی هرگز نمی‌تواند مستقیماً درون یک Measure به‌عنوان مقدار نهایی بازگردانده شود، مگر آنکه در ترکیب با توابعی مانند CALCULATE، COUNTROWS یا یک Iterator دیگر استفاده شود که بتواند این جدول را به یک مقدار Scalar تبدیل کند.

مثال پایه: فیلتر کردن جدول فروش بر اساس یک شرط

فرض کنید در یک سیستم فروش سازمانی، Measure پایه فروش کل را داریم.

Total Sales =
SUM ( Sales[Amount] )

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

High Value Sales =
CALCULATE (
    [Total Sales],
    FILTER (
        Sales,
        Sales[Amount] > 5000000
    )
)

در این Measure، FILTER جدول Sales را پیمایش می‌کند، برای هر ردیف شرط Amount بزرگ‌تر از پنج میلیون را بررسی می‌کند و جدولی جدید شامل فقط تراکنش‌های واجد شرط بازمی‌گرداند. سپس CALCULATE این جدول را به‌عنوان یک فیلتر جدید روی Filter Context اعمال می‌کند و Total Sales را در همین Context جدید محاسبه می‌کند.

مسیر اجرای داخلی این Measure

جدول Sales
        │
        ▼
پیمایش ردیف به ردیف توسط FILTER
        │
        ▼
ارزیابی شرط Amount > 5000000 برای هر ردیف
        │
        ▼
ساخت جدول جدید از ردیف‌های واجد شرط
        │
        ▼
CALCULATE این جدول را به‌عنوان فیلتر اعمال می‌کند
        │
        ▼
Total Sales در Filter Context جدید محاسبه می‌شود

تفاوت FILTER با فیلتر بولی مستقیم داخل CALCULATE

یکی از رایج‌ترین سؤالاتی که توسعه‌دهندگان تازه‌کار DAX می‌پرسند این است که چرا باید از FILTER استفاده کرد، در حالی که می‌توان همان شرط را مستقیماً به‌عنوان آرگومان دوم CALCULATE نوشت.

با FILTER:
CALCULATE (
    [Total Sales],
    FILTER ( Sales, Sales[Amount] > 5000000 )
)

بدون FILTER:
CALCULATE (
    [Total Sales],
    Sales[Amount] > 5000000
)

هر دو Measure از نظر منطقی همان نتیجه را تولید می‌کنند، اما مسیر اجرای آن‌ها در موتور DAX می‌تواند متفاوت باشد. حالت دوم که فیلتر به‌صورت مستقیم و بدون FILTER نوشته شده، یک Boolean Filter Expression ساده محسوب می‌شود که مدل‌های Import، به دلیل ساختار Column Store، معمولاً برای پردازش این نوع فیلتر بهینه شده‌اند. این حالت اغلب سریع‌ترین مسیر ممکن برای اعمال یک شرط ساده روی یک ستون است.

حالت اول که از FILTER استفاده می‌کند، شرط مشخص‌شده را برای ردیف‌های جدول ورودی ارزیابی می‌کند. از منظر Performance، استفاده از FILTER به‌خصوص روی جداول بزرگ یا همراه با Expressionهای پیچیده می‌تواند هزینه بیشتری ایجاد کند و ممکن است بخش بیشتری از پردازش را به Formula Engine وابسته کند. با این حال نباید صرفاً بر اساس ظاهر کد درباره Performance قضاوت کرد؛ موتور VertiPaq و DAX در بسیاری از سناریوهای ساده می‌تواند FILTER را بازنویسی یا بهینه کند، بنابراین رفتار واقعی هر Measure باید با ابزارهایی مانند DAX Studio اندازه‌گیری شود، نه صرفاً بر مبنای یک قاعده کلی.

چه زمانی FILTER مناسب‌تر است

برای شرط‌های ساده تک‌ستونی مانند مثال بالا، فیلتر مستقیم بدون FILTER معمولاً گزینه بهتری است. اما به محض آنکه شرط فیلتر نیازمند مقایسه بین چند ستون، فراخوانی یک Measure دیگر یا منطق شرطی پیچیده باشد، فیلتر بولی مستقیم دیگر پاسخگو نیست و استفاده از FILTER به‌عنوان یک Table Expression یکی از روش‌های استاندارد برای پیاده‌سازی این منطق می‌شود.

CALCULATE (
    [Total Sales],
    FILTER (
        Sales,
        Sales[Amount] > Sales[Budget]
    )
)

در این مثال، FILTER امکان ارزیابی شرطی را فراهم می‌کند که مستقیماً روی هر ردیف جدول Sales بررسی می‌شود. این نوع Table Expression زمانی اهمیت بیشتری پیدا می‌کند که منطق فیلتر از یک شرط ساده ستونی فراتر برود.

مثال دیگر با فراخوانی یک Measure:

CALCULATE (
    [Total Sales],
    FILTER (
        VALUES ( Product[ProductName] ),
        [Total Sales] > 100000000
    )
)

در این Measure، برای هر محصول، مقدار Total Sales محاسبه و با یک آستانه مقایسه می‌شود. از آنجا که Boolean Filter Expression نمی‌تواند یک Measure را مستقیماً به‌عنوان شرط فیلتر دریافت کند، در چنین سناریویی استفاده از FILTER روی VALUES یکی از روش‌های استاندارد و توصیه‌شده برای پیاده‌سازی این منطق است.

ترکیب FILTER با VALUES برای فیلتر بر اساس نتیجه محاسبه

یکی از الگوهای بسیار رایج در پروژه‌های سازمانی، ترکیب FILTER با VALUES برای فیلتر کردن اعضای یک بعد بر اساس نتیجه یک محاسبه، نه بر اساس مقدار خام یک ستون است.

Above Average Products Sales =
CALCULATE (
    [Total Sales],
    FILTER (
        VALUES ( Product[ProductName] ),
        [Total Sales] > [Average Product Sales]
    )
)

در این Measure، ابتدا VALUES مجموعه محصولات موجود در Context فعلی را برمی‌گرداند، سپس FILTER برای هر محصول، مقدار Total Sales را با میانگین فروش تمام محصولات مقایسه می‌کند و فقط محصولاتی را نگه می‌دارد که فروش آن‌ها از میانگین بیشتر است. این الگو در شناسایی محصولات پرفروش‌تر از میانگین، مشتریان با ارزش بالاتر از حد معمول و سناریوهای مشابه بسیار پرکاربرد است.

استفاده از VALUES(Product[ProductName]) باعث می‌شود FILTER دقیقاً روی مجموعه مقادیر یکتای نام محصول کار کند. از آنجا که VALUES در Filter Context فعلی ارزیابی می‌شود، دامنه محصولات نیز با فیلترهای موجود در گزارش هماهنگ خواهد بود. این الگو به‌خصوص زمانی مفید است که قصد داریم یک Measure را برای هر عضو از یک Dimension، در همان محدوده‌ای که کاربر در گزارش می‌بیند، ارزیابی کنیم.

ترکیب FILTER با ALL برای نادیده گرفتن فیلترهای فعلی

در بسیاری از سناریوهای تحلیلی، نیاز داریم فیلتر جدید را نه بر اساس Context فعلی، بلکه بر اساس کل مجموعه داده اعمال کنیم. در این حالت، FILTER معمولاً همراه با ALL به کار می‌رود.

Products Above Fixed Threshold =
CALCULATE (
    [Total Sales],
    FILTER (
        ALL ( Product[ProductName] ),
        [Total Sales] > 50000000
    )
)

در این Measure، ALL(Product[ProductName]) فیلتر موجود روی ستون ProductName را حذف می‌کند و FILTER را روی تمام مقادیر نام محصول ارزیابی می‌کند. سایر فیلترهای جدول Product، مانند Category یا Color، همچنان می‌توانند در Context باقی بمانند، زیرا ALL در این نوشتار فقط محدود به همان ستونی است که به‌صراحت در آرگومان آن قید شده است.

اگر هدف حذف تمام فیلترهای جدول Product باشد، باید از ALL(Product) به‌جای ALL( Product[ProductName]) استفاده شود.

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

استفاده از FILTER برای ساخت جدول‌های شرطی چندستونی

یکی از قدرتمندترین کاربردهای FILTER، ترکیب چند شرط منطقی برای ساخت یک جدول فیلترشده پیچیده است.

Qualified Customers Sales =
CALCULATE (
    [Total Sales],
    FILTER (
        Customer,
        Customer[CustomerType] = "Corporate"
            && Customer[CreditRating] = "A"
            && [Total Sales] > 200000000
    )
)

در این مثال، FILTER جدول Customer را پیمایش می‌کند و تنها مشتریانی را نگه می‌دارد که هم‌زمان از نوع سازمانی باشند، رتبه اعتباری A داشته باشند و فروش آن‌ها از یک آستانه معین بیشتر باشد. چنین ترکیبی را می‌توان با یک Table Expression مانند FILTER پیاده‌سازی کرد، زیرا شرط نهایی به مقدار یک Measure وابسته است و Boolean Filter Expression مستقیم امکان چنین ترکیبی از شرط‌های ستونی و محاسباتی را ندارد.

FILTER به‌عنوان جدول ورودی برای Iteratorهای دیگر

از آنجا که خروجی FILTER یک جدول است، این تابع اغلب به‌عنوان جدول ورودی برای X Functionها یا سایر توابعی که یک جدول می‌پذیرند، مانند RANKX، TOPN یا SUMX، به کار می‌رود.

Discounted Revenue =
SUMX (
    FILTER (
        Sales,
        Sales[DiscountRate] > 0
    ),
    Sales[Amount] * ( 1 - Sales[DiscountRate] )
)

در این Measure، ابتدا FILTER تراکنش‌هایی را که تخفیف دارند از جدول Sales استخراج می‌کند، سپس SUMX روی همین جدول فیلترشده پیمایش می‌کند و مبلغ نهایی پس از اعمال تخفیف را برای هر ردیف محاسبه و جمع می‌زند. این ترکیب یکی از رایج‌ترین الگوها در محاسبات مالی و تحلیلی است که نیاز به اعمال یک شرط پیش از یک محاسبه سطر به سطر دارند.

تفاوت FILTER با CALCULATETABLE

نکته‌ای که گاهی باعث سردرگمی می‌شود، شباهت ظاهری FILTER با CALCULATETABLE است. هر دو یک جدول بازمی‌گردانند، اما منطق داخلی آن‌ها متفاوت است.

FILTER دقیقاً همان رفتار پیمایش ردیف به ردیف و ارزیابی یک شرط بولی برای هر ردیف را دارد که پیش‌تر توضیح داده شد. CALCULATETABLE در مقابل، معادل جدولی CALCULATE است؛ یعنی یک Table Expression را در یک Filter Context جدید ارزیابی می‌کند، دقیقاً مشابه رفتار CALCULATE برای Measureها، اما با خروجی جدولی به‌جای اسکالر.

CALCULATETABLE (
    Sales,
    Sales[Year] = 2025
)

این Expression جدول Sales را در Context سال ۲۰۲۵ بازمی‌گرداند، با استفاده از همان منطق تغییر Filter Context که در CALCULATE دیدیم، نه با پیمایش ردیف به ردیف و ارزیابی شرط برای هر رکورد. در سناریوهایی که هدف صرفاً ارزیابی یک Table Expression در Filter Context جدید است و نیازی به پیمایش شرطی ردیف‌به‌ردیف وجود ندارد، CALCULATETABLE می‌تواند انتخاب مناسب‌تری باشد. با این حال، انتخاب بین این دو تابع باید بر اساس منطق محاسبه و Performance واقعی هر Measure انجام شود، نه یک قاعده ثابت.

FILTER و KEEPFILTERS چه تفاوتی دارند

نکته‌ای که در کنار FILTER و CALCULATE اغلب مطرح می‌شود، رفتار KEEPFILTERS است. FILTER یک Table Expression تولید می‌کند، در حالی که KEEPFILTERS رفتار اعمال فیلتر در CALCULATE و CALCULATETABLE را تغییر می‌دهد؛ بنابراین این دو تابع جایگزین یکدیگر نیستند و در دو سطح متفاوت عمل می‌کنند.

اگر ستون یا جدول مورد فیلتر در Filter Context فعلی وجود داشته باشد، رفتار پیش‌فرض CALCULATE برای Filter Argument می‌تواند فیلتر موجود را روی همان ستون یا جدول جایگزین کند؛ KEEPFILTERS این رفتار را تغییر می‌دهد و اجازه می‌دهد فیلتر جدید با فیلتر موجود ترکیب شود.

Red Sales =
CALCULATE (
    [Total Sales],
    KEEPFILTERS ( Product[Color] = "Red" )
)

در این مثال، اگر از قبل روی Product[Color] فیلتری وجود داشته باشد، KEEPFILTERS باعث می‌شود فیلتر جدید با فیلتر قبلی ترکیب شود، نه اینکه به‌صورت پیش‌فرض آن را جایگزین کند. این رفتار در مدل‌های تحلیلی با چند لایه Filter Context، به‌خصوص در ترکیب با Measureهایی که از FILTER یا CALCULATETABLE استفاده می‌کنند، اهمیت زیادی دارد و شناخت آن مکمل درک صحیح رفتار FILTER و CALCULATE است.

تأثیر FILTER بر Performance در مدل‌های حجیم

از دید معنایی DAX، FILTER جدول ورودی را بررسی می‌کند و شرط آن برای ردیف‌های جدول ارزیابی می‌شود؛ در نتیجه، استفاده از FILTER می‌تواند نسبت به یک Boolean Filter Expression ساده، نیازمند پردازش بیشتری باشد، به‌خصوص زمانی که جدول ورودی بزرگ یا Expression پیچیده باشد.

تأثیر اندازه جدول ورودی

هرچه جدول ورودی FILTER بزرگ‌تر باشد، هزینه پیمایش و ارزیابی شرط برای هر ردیف نیز معمولاً بیشتر می‌شود. در جداول Fact با میلیون‌ها رکورد، اجرای FILTER مستقیماً روی کل جدول، بدون هیچ محدودیت اولیه، می‌تواند به یکی از عوامل مؤثر بر کندی گزارش تبدیل شود.

پرهزینه در حجم بالا:
CALCULATE (
    [Total Sales],
    FILTER (
        Sales,
        Sales[Amount] > 5000000
    )
)

اگر همین شرط بتواند به‌صورت فیلتر بولی مستقیم نوشته شود، معمولاً گزینه بهینه‌تری است، زیرا مدل‌های Import بر پایه Column Store برای چنین فیلترهایی بهینه شده‌اند.

بهینه‌تر:
CALCULATE (
    [Total Sales],
    Sales[Amount] > 5000000
)

پیچیدگی Expression داخل FILTER

هرچه شرط داخل FILTER پیچیده‌تر باشد، به‌خصوص اگر شامل فراخوانی Measureهای دیگر یا Context Transition باشد، هزینه اجرایی نیز افزایش می‌یابد.

بسیار پرهزینه:
FILTER (
    Customer,
    CALCULATE (
        SUMX (
            RELATEDTABLE ( Sales ),
            Sales[Amount]
        )
    ) > 100000000
)

در این مثال، برای هر مشتری، یک Context Transition و سپس یک SUMX روی جدول مرتبط اجرا می‌شود، و این عملیات برای تمام اعضای جدول Customer تکرار می‌شود. در جداول بزرگ، چنین ساختاری می‌تواند فشار قابل توجهی به Formula Engine وارد کند. در چنین شرایطی، توصیه می‌شود بررسی شود که آیا می‌توان با تغییر ساختار Query یا استفاده از یک Measure میانی، بخشی از این محاسبه را ساده‌تر یا به Storage Engine نزدیک‌تر کرد.

بررسی رفتار FILTER با DAX Studio

برای تحلیل دقیق هزینه اجرایی یک Measure مبتنی بر FILTER، استفاده از DAX Studio و بررسی Server Timings توصیه می‌شود. در این تحلیل معمولاً می‌توان مشاهده کرد که آیا FILTER توانسته بخشی از منطق خود را به Storage Engine منتقل کند یا عمدتاً در Formula Engine پردازش شده است. در بسیاری از موارد ساده، حتی زمانی که از FILTER استفاده شده، موتور DAX می‌تواند آن را بازنویسی و بهینه کند، اما این بهینه‌سازی همیشه تضمین‌شده نیست و باید با اندازه‌گیری واقعی روی داده سازمان بررسی شود.

اشتباهات رایج در استفاده از FILTER

استفاده از FILTER برای شرط‌های ساده تک‌ستونی

رایج‌ترین اشتباه، استفاده از FILTER برای شرط‌هایی است که می‌توانند به‌سادگی به‌صورت فیلتر بولی مستقیم در CALCULATE نوشته شوند. این کار موتور را مجبور به پیمایش ردیف به ردیف می‌کند، در حالی که فیلتر مستقیم می‌تواند از مسیر بهینه‌تر Storage Engine بهره ببرد.

فراموش کردن ALL هنگام نیاز به نادیده گرفتن Context فعلی

اگر هدف اعمال فیلتر بر اساس کل مجموعه داده باشد، نه فقط اعضای قابل مشاهده در Context فعلی، فراموش کردن ALL در جدول ورودی FILTER می‌تواند نتیجه‌ای کاملاً متفاوت با انتظار تولید کند، زیرا FILTER بدون ALL تنها روی اعضای موجود در Filter Context فعلی عمل می‌کند.

تودرتو کردن بیش از حد FILTER و CALCULATE

استفاده از چند لایه FILTER و CALCULATE تودرتو، به‌خصوص در ترکیب با Iteratorهای دیگر، می‌تواند خوانایی کد را کاهش دهد و هزینه اجرایی را به شکل غیرقابل پیش‌بینی افزایش دهد. در چنین شرایطی، بازبینی منطق و در صورت امکان ساده‌سازی آن با Measureهای میانی توصیه می‌شود.

استفاده از FILTER به‌جای CALCULATETABLE در سناریوهای ساده

در مواردی که هدف صرفاً اعمال یک یا چند فیلتر بولی ساده روی یک جدول است، بدون نیاز به منطق شرطی پیچیده سطر به سطر، استفاده از CALCULATETABLE به‌جای FILTER می‌تواند خوانایی کد را بهبود دهد و در برخی سناریوها از نظر Performance نیز مزیت داشته باشد.

Best Practiceهای استفاده از FILTER در پروژه‌های سازمانی

پیش از استفاده از FILTER، باید بررسی شود که آیا شرط موردنظر می‌تواند به‌صورت فیلتر بولی مستقیم در CALCULATE نوشته شود. اگر شرط تنها شامل مقایسه یک ستون با یک مقدار یا مجموعه‌ای از مقادیر ثابت است، فیلتر مستقیم معمولاً انتخاب بهتری است.

زمانی که منطق فیلتر فقط به مجموعه‌ای از مقادیر یک ستون نیاز دارد، استفاده از VALUES روی همان ستون می‌تواند دامنه کاری FILTER را نسبت به پیمایش یک جدول بزرگ‌تر محدود کند. با این حال، تأثیر واقعی این تغییر باید با اندازه‌گیری روی مدل موردنظر بررسی شود.

Expression داخل FILTER باید تا حد امکان ساده نگه داشته شود. اگر محاسبه پایه پیچیده است، تعریف آن در یک Measure مستقل و سپس فراخوانی آن داخل FILTER، هم خوانایی و هم امکان بهینه‌سازی را بهبود می‌دهد.

استفاده از ALL در ترکیب با FILTER باید آگاهانه و بر اساس نیاز واقعی گزارش انجام شود؛ فراموش کردن آن می‌تواند نتیجه‌ای کاملاً متفاوت با انتظار تولید کند، در حالی که استفاده نادرست از آن روی کل جدول به‌جای یک ستون مشخص نیز می‌تواند فیلترهای دیگری را که باید فعال باقی بمانند حذف کند.

در سناریوهایی که فیلتر جدید باید با فیلتر موجود روی همان ستون ترکیب شود، نه جایگزین آن، استفاده از KEEPFILTERS باید مورد بررسی قرار گیرد.

پیش از استقرار Measureهای مبتنی بر FILTER روی جداول بزرگ در محیط عملیاتی، Performance آن‌ها باید با DAX Studio روی داده واقعی سازمان اندازه‌گیری شود، به‌خصوص اگر Expression داخل FILTER شامل فراخوانی Measureهای دیگر یا Context Transition باشد.

جمع‌بندی

FILTER یکی از توابع بنیادین DAX است که با ساخت یک جدول مجازی بر اساس یک شرط منطقی، امکان پیاده‌سازی محاسبات شرطی پیچیده‌ای را فراهم می‌کند که با فیلتر بولی ساده در CALCULATE قابل انجام نیستند. این تابع به‌خصوص در سناریوهایی که شرط فیلتر نیازمند مقایسه بین چند ستون، فراخوانی یک Measure یا ترکیب چند شرط منطقی است، ابزاری استاندارد و کاربردی محسوب می‌شود.

با این حال، از منظر Performance، FILTER همیشه انتخاب بهینه نیست. برای شرط‌های ساده تک‌ستونی، فیلتر بولی مستقیم در CALCULATE اغلب مسیر اجرایی سریع‌تری دارد، زیرا می‌تواند امکان بهره‌گیری مؤثرتر از پردازش ستونی Storage Engine را فراهم کند. تشخیص درست این‌که کدام سناریو واقعاً به FILTER نیاز دارد و کدام یک می‌تواند با روش ساده‌تری مانند فیلتر بولی مستقیم یا CALCULATETABLE پیاده‌سازی شود، همراه با شناخت مکمل‌هایی مانند KEEPFILTERS، یکی از مهارت‌های کلیدی طراحی Measureهای بهینه در پروژه‌های سازمانی Power BI است.

سوالات متداول FAQ

چرا نمی‌توان FILTER را مستقیماً به‌عنوان مقدار خروجی یک Measure برگرداند؟
زیرا خروجی FILTER همیشه یک جدول است، نه یک مقدار Scalar. برای استفاده در یک Measure، باید نتیجه FILTER در ترکیب با CALCULATE، COUNTROWS، یک Iterator یا تابعی دیگر که جدول را به یک مقدار تبدیل می‌کند، به کار رود.

تفاوت اصلی FILTER با فیلتر بولی مستقیم در CALCULATE چیست؟
فیلتر بولی مستقیم برای شرط‌های ساده روی یک ستون طراحی شده و مدل‌های Import معمولاً برای پردازش آن بهینه شده‌اند. FILTER جدول ورودی را ردیف به ردیف پیمایش و شرط را برای هر ردیف ارزیابی می‌کند و برای شرط‌های پیچیده‌تر، مانند مقایسه چند ستون یا فراخوانی یک Measure، لازم می‌شود.

چه زمانی باید از CALCULATETABLE به‌جای FILTER استفاده کرد؟
زمانی که هدف صرفاً اعمال یک یا چند فیلتر بولی ساده روی یک جدول است، بدون نیاز به منطق شرطی سطر به سطر، CALCULATETABLE معمولاً گزینه ساده‌تر و در برخی سناریوها بهینه‌تری است.

تفاوت FILTER و KEEPFILTERS چیست؟
FILTER یک Table Expression است که جدولی فیلترشده تولید می‌کند، در حالی که KEEPFILTERS رفتار CALCULATE و CALCULATETABLE را در برابر فیلترهای موجود تغییر می‌دهد و باعث ترکیب فیلتر جدید با فیلتر قبلی به‌جای جایگزینی آن می‌شود. این دو تابع در دو سطح متفاوت عمل می‌کنند و جایگزین یکدیگر نیستند.

آیا FILTER همیشه باعث کندی Query می‌شود؟
نه لزوماً. در جداول کوچک یا شرط‌های ساده، هزینه اضافه FILTER معمولاً ناچیز است و موتور DAX در بسیاری موارد می‌تواند آن را بهینه کند. کندی بیشتر زمانی محسوس می‌شود که جدول ورودی بزرگ باشد یا Expression داخل FILTER شامل محاسبات پیچیده و فراخوانی Measureهای دیگر باشد؛ در این موارد بررسی با DAX Studio توصیه می‌شود.

آیا همیشه باید از FILTER داخل CALCULATE استفاده کنیم؟
خیر. برای شرط‌های ساده‌ای که می‌توان آن‌ها را به‌صورت Boolean Filter Expression در CALCULATE نوشت، معمولاً استفاده مستقیم از شرط خواناتر و از نظر Performance مناسب‌تر است. FILTER زمانی ارزش بیشتری پیدا می‌کند که منطق فیلتر به ارزیابی یک Expression، Measure یا شرایط پیچیده‌تر نیاز داشته باشد.

پیشنهاد مطالعه

بهینه‌سازی DAX و Power BI را به لاندا بسپارید

اگر در مدل Power BI سازمان شما Measureهای پیچیده، محاسبات کند یا مشکلاتی مانند Filter Context نادرست، استفاده نامناسب از FILTER و افت Performance وجود دارد، تیم توسعه فناوری اطلاعات لاندا می‌تواند در طراحی و بهینه‌سازی مدل‌های تحلیلی، Measureهای پیشرفته DAX و Performance گزارش‌های Power BI در کنار شما باشد.

از طراحی مدل داده و بازنویسی Measureهای پیچیده تا تحلیل Performance با ابزارهایی مانند DAX Studio، هدف ما ساخت گزارش‌هایی دقیق، سریع و مقیاس‌پذیر برای محیط‌های سازمانی است.

اگر Performance گزارش‌های Power BI شما رضایت‌بخش نیست، زمان آن رسیده است که منطق DAX و مدل داده را تخصصی بررسی کنید.
با کارشناسان لاندا تماس  بگیرید.

No comment

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *