تجزیه و تحلیل عملکرد روابط Limited و Regular در مدلهای دادهی Power BI
فهرست مطالب
روابط در مدلهای داده چیست؟
در یک مدل دادهٔ semantic در Power BI، دو نوع رابطهی اصلی وجود دارد:
رابطهٔ Regular: معمولترین نوع، یک رابطه یکبهچند (one-to-many) بین دو جدول در یک data island (جزیرهٔ داده).
رابطهٔ Limited: زمانی رخ میدهد که جداول در data islandهای متفاوت باشند یا رابطهای با many-to-many داشته باشیم.
یک ارتباط یا رابطه در Power BI وقتی limited است که موتور DAX نتواند از ساختارهای بهینهی پیوست (join) استفاده کند.
نماد تفاوت در Power BI اینگونه نمایش داده میشود:
رابطهٔ regular بدون فاصله در خط اتصال،
رابطهٔ limited با فاصلهٔ کوچک در انتهای خط.
چرا انتخاب نوع رابطه اهمیت دارد؟
هر بار که DAX بخواهد یک جدول را اسکن کند و آن را group by بزند، از رابطه استفاده میشود.
یک رابطهٔ کند میتواند تمام Measures را که از آن رابطه عبور میکنند کند کند. sqlbi.com
انتخاب پایگاه داده برای تست
برای مقایسهٔ عملکرد بین دو نوع رابطه، باید تست واقعی روی دادههای بزرگ انجام شود:
مدل ساده Contoso 10K با ۴,۰۰۰ رکورد در جدول Sales آنقدر کوچک است که تفاوت در زمان اجرا گم میشود. بنابراین برای تست از مدلی با ۱.۴ میلیارد رکورد در جدول Sales استفاده شد. sqlbi.com
اندازهگیری عملکرد: سناریوی ساده
ابتدا میخواهیم مقدار Sales Amount را بدون استفاده از هیچ رابطهای محاسبه کنیم؛ این به ما هزینهٔ اسکن جدول را میدهد.
EVALUATE
SUMMARIZECOLUMNS (
"Sales", [Sales Amount]
)
این کوئری جدول Sales را اسکن میکند و مجموع فروش را برمیگرداند.
زمان اجرای واقعی (SE CPU) بیش از ۷ ثانیه بود که به دلیل Parallelism در زمان واقعی کوتاهتر به نظر رسید اما هزینهٔ واقعی CPU بالا بود.
اضافه کردن رابطهٔ Regular
حالا جدول Sales را گروهبندی میکنیم بهوسیلهٔ فیلد Customer[Country] با استفاده از رابطه بین Sales و Customer.
EVALUATE
SUMMARIZECOLUMNS (
Customer[Country],
"Sales", [Sales Amount]
)
اینجا موتور VertiPaq رابطه را بهصورت یک join داخلی استفاده میکند. نتیجهٔ این تست نشان داد که زمان اجرا تقریباً دو برابر میشود چون هزینهٔ رابطه اضافه شده است.
نکتهٔ مهم:
هزینهٔ رابطهٔ به تعداد رکوردهای جدول سمت one وابسته است؛ چنانکه Customer حدود ۱.۸ میلیون رکورد داشت.
تبدیل رابطه به Limited
اکنون رابطهٔ بین Sales و Customer را از یکبهچند به Many-to-Many تغییر میدهیم — نتیجه اینکه رابطه limited میشود.
همان کوئری با رابطهٔ limited:
EVALUATE
SUMMARIZECOLUMNS (
Customer[Country],
"Sales", [Sales Amount]
)
نتایج سرور نشان داد که SE CPU از ~15,000ms به ~138,000ms افزایش یافت.
اگر هزینهٔ اسکن جدول را (~7,000ms) از این عدد کم کنیم، هزینهٔ واقعی اضافهشدهٔ رابطه حدود 131,000ms است!
📌 این یعنی بیش از ۲۰ برابر هزینهٔ بیشتر نسبت به رابطهٔ regular فقط بهخاطر many-to-many بودن آن.
سناریوی پیشرفته: چند Measure
در سناریوی بعدی، میخواهیم مقدار فروش را جداگانه برای مشتریان Male و Female در یک کوئری محاسبه کنیم:
EVALUATE
SUMMARIZECOLUMNS (
Customer[Country],
"Male Sales", CALCULATE ( [Sales Amount], Customer[Gender] = "Male" ),
"Female Sales", CALCULATE ( [Sales Amount], Customer[Gender] = "Female" )
)
با رابطهٔ regular، موتور DAX قادر است این کوئری را فقط با یک درخواست به Storage Engine انجام دهد (استفاده از Fusion optimization).
اما وقتی رابطه limited باشد، موتور نمیتواند این کار را در یک مرحله انجام دهد و مجبور است دو عملیات مجزا انجام دهد — یکی برای Male Sales و دیگری برای Female Sales.
این موضوع باعث میشود اجرای کوئری بسیار پیچیدهتر و کندتر شود.
نتیجهگیری: چه زمانی کدام رابطه بهتر است؟
رابطهٔ Many-to-Many (که بهطور ذاتی limited است) ویژگی مدلسازی قدرتمندی بهنظر میرسد،
اما در عمل باعث کندی چشمگیر اجرای کوئریها میشود.
📌 توصیههای عملی:
استفاده از many-to-many تنها وقتی منطقی است که واقعاً ضروری باشد.
اگر ستونهای کلیدی دارای میلیونها مقدار یکتا هستند، بهتر است از بسیاریبهچند many-to-many اجتناب کنید.
برای cardinalities کوچکتر (مثلاً هزار یا کمتر)، ممکن است هزینهٔ اضافه قابلقبول باشد.
نکات کلیدی برای توسعهدهندگان Power BI
روابط limited زمانی اتفاق میافتد که جدولها در data islandهای مجزا باشند یا cardinality در طرف “one” نامشخص باشد.
تفاوت عملکرد بین regular و limited در کوئریهای پیچیده بسیار مشهودتر است.
استفاده از تستهای واقعی با دادههای بزرگ برای اندازهگیری دقیق عملکرد ضروری است
دیدگاهتان را بنویسید