Scalar UDF Inlining در T-SQL؛ آموزش کامل TSQL_SCALAR_UDF_INLINING در SQL Server
Scalar UDF کد را تمیز میکند، اما در مدل سنتی میتواند هزینه ردیفبهردیف پنهان داشته باشد. Inlining میخواهد خوانایی تابع را با دید بهتر Optimizer جمع کند.
Scalar UDF سنتی میتواند هزینه واقعی خود را از Optimizer پنهان کند. Inlining در شرایط واجد صلاحیت منطق تابع را وارد Plan اصلی میکند تا Optimizer دید بهتری داشته باشد. در این مقاله از Syntax و خواندن مقدار فعلی شروع میکنیم و بعد به سناریوی واقعی، روش اندازهگیری، خطاهای رایج و تصمیم Production میرسیم.
برای دیدن ارتباط این گزینه با سایر تنظیمات، راهنمای جامع Database Scoped Performance Configuration را هم ببینید.
تعریف و منطق فنی
تبدیل برخی Scalar UDFهای واجد شرایط به عبارت Relational داخل Query برای حذف سربار فراخوانی ردیفبهردیف.
Scalar UDF سنتی میتواند هزینه واقعی خود را از Optimizer پنهان کند. Inlining در شرایط واجد صلاحیت منطق تابع را وارد Plan اصلی میکند تا Optimizer دید بهتری داشته باشد.
اصل عملی: تنظیم Performance فقط وقتی ارزش دارد که مسئله، معیار موفقیت و راه برگشت آن از قبل روشن باشد.
Syntax اصلی
ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = ON;
مقادیر و رفتار
- مقدار یا فرمان: ON یا OFF.
- سناریوی مناسب: گزارشی که Scalar UDF محاسبه تخفیف را برای صدها هزار ردیف صدا میزند
- ریسک اصلی: همه UDFها Inline نمیشوند و تغییر Plan میتواند Memory Grant یا Join Order را عوض کند.
- نکته نسخه: Scalar UDF Inlining از SQL Server 2019 و Compatibility Level 150 یکی از قابلیتهای Intelligent Query Processing است.
این نقشه رابطه TSQL_SCALAR_UDF_INLINING را با Inlining، Relational و شاخصهای Runtime نشان میدهد. تصویر برای فهم دامنه اثر است و جای Execution Plan واقعی را نمیگیرد.
چطور قبل از تغییر تصمیم بگیریم
قبل از اجرای تغییر، Queryهای نماینده را بر اساس اهمیت تجاری و مصرف منابع جدا کنید. Plan آنها را در Query Store نگه دارید و فقط یک متغیر را تغییر دهید. اگر همزمان Index، Compatibility Level و TSQL_SCALAR_UDF_INLINING را عوض کنید، Attribution نتیجه از بین میرود.
معیار تک Query و معیار کل Workload را جدا ببینید. ممکن است یک Query سریعتر شود اما Throughput کل افت کند. همه UDFها Inline نمیشوند و تغییر Plan میتواند Memory Grant یا Join Order را عوض کند. به همین دلیل Concurrency و مصرف منابع باید کنار زمان پاسخ سنجیده شود.
اشتباه رایج: فرضکردن اینکه هر Scalar UDF با روشنشدن گزینه حتماً Inline میشود. راه حرفهای این است که فرضیه، Baseline، Change و Rollback در یک سند کوتاه و قابل بازبینی ثبت شوند.
جریان TSQL_SCALAR_UDF_INLINING از مشاهده وضعیت، اعمال Change، Compile یا Runtime Behavior و سپس Measure عبور میکند. نقاط اندازهگیری قبل و بعد باید یکسان باشند.
۱۰ مثال عملی و قابل اجرا
مثال 1: مشاهده وضعیت واقعی قبل از تغییر
برای Scalar UDF Inlining در T-SQL اولین قدم تغییر نیست؛ ثبت وضعیت فعلی است. خروجی را همراه زمان، نسخه و نام Database نگه دارید تا Baseline قابل استناد باشد.
SELECT name, value, value_for_secondary
FROM sys.database_scoped_configurations
WHERE name = N'TSQL_SCALAR_UDF_INLINING';
| name | value | برداشت |
|---|
| TSQL_SCALAR_UDF_INLINING | مقدار فعلی | از همان سرور خوانده شود |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
مثال 2: فعالسازی کنترلشده در محیط آزمایشی
در این سناریو TSQL_SCALAR_UDF_INLINING را فقط جایی تغییر میدهیم که Baseline داریم. یک اجرای سریع برای تصمیم نهایی کافی نیست و باید چند چرخه کاری قابل مقایسه سنجیده شود.
ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = ON;
| عملیات | خروجی نمونه | کنترل |
|---|
| TSQL_SCALAR_UDF_INLINING | Command completed successfully | مقدار دوباره خوانده شود |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
مثال 3: بازگشت مستند به رفتار قبلی
Performance Change بدون Rollback کامل نیست. چون همه UDFها Inline نمیشوند و تغییر Plan میتواند Memory Grant یا Join Order را عوض کند.، فرمان بازگشت باید پیش از Deployment آماده باشد و تیم در زمان Incident بداههکاری نکند.
ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = OFF;
| Rollback | خروجی نمونه | معیار |
|---|
| TSQL_SCALAR_UDF_INLINING | Command completed successfully | رفتار قبلی تأیید شود |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
مثال 4: بررسی Compatibility Level
بسیاری از قابلیتها به Compatibility Level وابستهاند. پیش از نتیجهگیری درباره TSQL_SCALAR_UDF_INLINING، نسخه Engine و سطح سازگاری Database را کنار هم ثبت کنید.
SELECT DB_NAME() AS DatabaseName, compatibility_level
FROM sys.databases
WHERE database_id = DB_ID();
| Database | compatibility_level | نکته |
|---|
| CurrentDatabase | 150/160/170 | وابسته به نسخه و محیط |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
مثال 5: مقایسه قبل و بعد با Query Store
Query Store امکان دیدن Plan و Runtime را در دو بازه زمانی میدهد. برای Scalar UDF Inlining در T-SQL این داده تاریخی بسیار قابل اعتمادتر از یک Screenshot یا حس کلی کاربر است.
SELECT TOP (20) qsq.query_id, qsp.plan_id, rs.avg_duration, rs.avg_cpu_time
FROM sys.query_store_query AS qsq
JOIN sys.query_store_plan AS qsp ON qsp.query_id = qsq.query_id
JOIN sys.query_store_runtime_stats AS rs ON rs.plan_id = qsp.plan_id
ORDER BY rs.avg_duration DESC;
| منبع | خروجی | تفسیر |
|---|
| Query Store | Plan/Runtime rows | بازه قبل و بعد همسطح باشد |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
مثال 6: ساخت Workload کوچک و قابل تکرار
Workload آزمایشی باید همان رفتاری را تحریک کند که Feature برای آن ساخته شده است: تبدیل برخی Scalar UDFهای واجد شرایط به عبارت Relational داخل Query برای حذف سربار فراخوانی ردیفبهردیف. Query خیلی کوچک ممکن است هیچ تفاوتی نشان ندهد.
CREATE OR ALTER FUNCTION dbo.ufn_AddTax(@Amount decimal(18,2))
RETURNS decimal(18,2)
AS
BEGIN
RETURN @Amount * 1.09;
END;
| Metric | نمونه | نکته |
|---|
| Elapsed/CPU/Reads | وابسته به داده | چند اجرا مقایسه شود |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
مثال 7: خواندن شاخص Runtime مرتبط
یک DMV بهتنهایی حقیقت کامل Performance نیست. برای TSQL_SCALAR_UDF_INLINING داده Runtime را کنار Execution Plan، Query Store و وضعیت منابع قرار دهید.
SELECT o.name, sm.is_inlineable, sm.inline_type
FROM sys.sql_modules sm JOIN sys.objects o ON o.object_id=sm.object_id
WHERE o.type='FN';
| Runtime signal | نمونه | برداشت |
|---|
| Relational | قابل اندازهگیری | روند مهمتر از Snapshot است |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
مثال 8: پیداکردن Queryهای پرریسک
بهجای جستوجوی تصادفی، Queryهای پرتکرار یا پرمصرف را جدا کنید و ببینید آیا مشکل واقعاً با تبدیل برخی Scalar UDFهای واجد شرایط به عبارت Relational داخل Query برای حذف سربار فراخوانی ردیفبهردیف ارتباط دارد یا علت اصلی Statistics، Index، Blocking یا طراحی Query است.
SELECT TOP (20) qs.execution_count, qs.total_worker_time, qs.total_elapsed_time,
SUBSTRING(st.text,1,300) AS sample_sql
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
ORDER BY qs.total_worker_time DESC;
| Query | نشانه | اقدام |
|---|
| Top workload | CPU/Duration/Spill | Plan واقعی بررسی شود |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
مثال 9: قرار دادن Guard در Deployment
Deployment حرفهای باید Fail Fast باشد. Guard نسخهای کمک میکند تغییر TSQL_SCALAR_UDF_INLINING روی محیطی که ارزیابی نشده اجرا نشود و رفتار غیرمنتظره نسازد.
IF CAST(SERVERPROPERTY('ProductMajorVersion') AS int) >= 13
BEGIN
ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = ON;
END
ELSE
THROW 50010, N'نسخه موتور برای این Deployment بررسی شود.', 1;
| Deployment | Result | Safety |
|---|
| Version guard | Pass/Throw | اجرای کنترلشده |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
مثال 10: Rollback و تأیید مقدار نهایی
Rollback فقط اجرای Command معکوس نیست. مقدار نهایی، Planهای مهم و Metricهای Baseline باید دوباره کنترل شوند تا بازگشت واقعاً تأیید شود.
-- Rollback کنترلشده
ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = OFF;
SELECT name, value, value_for_secondary
FROM sys.database_scoped_configurations
WHERE name = N'TSQL_SCALAR_UDF_INLINING';
| مرحله | خروجی | معیار پایان |
|---|
| Rollback | تنظیم قبلی | Baseline دوباره کنترل شود |
خروجی جدول فقط شکل نمونه نتیجه را نشان میدهد. مقدار واقعی TSQL_SCALAR_UDF_INLINING به نسخه، داده و بار سیستم شما وابسته است؛ خروجی واقعی را با Timestamp ذخیره کنید.
خطاهای رایج
- فرضکردن اینکه هر Scalar UDF با روشنشدن گزینه حتماً Inline میشود.
- اعمال چند تغییر Performance در یک Release و از دست دادن امکان تشخیص علت.
- مقایسه Warm Cache با Cold Cache و نتیجهگیری قطعی.
- نادیده گرفتن تفاوت نسخه، CU و Compatibility Level بین Test و Production.
- تمرکز فقط روی Duration و ندیدن CPU، Reads، Memory، Spill، Blocking یا Throughput.
Performance Considerations
اثر TSQL_SCALAR_UDF_INLINING را با Metric همان Feature بسنجید. مفاهیم کلیدی این مقاله: Scalar UDF, Inlining, Relational, CPU, Compatibility 150. اگر معیار انتخابی با این زنجیره ارتباطی ندارد، آزمایش ممکن است نتیجه گمراهکننده بدهد.
همه UDFها Inline نمیشوند و تغییر Plan میتواند Memory Grant یا Join Order را عوض کند. این ریسک دلیل طراحی آزمایش بهتر است، نه دلیل تصمیم عجولانه. Query Store، Actual Plan و DMVهای Runtime را کنار هم ببینید.
بهترین روشها
- مقدار فعلی، نسخه Engine و Compatibility Level را ثبت کنید.
- Baseline Queryهای حیاتی را بگیرید.
- تغییر را ابتدا در محیط مشابه Production یا بازه کمریسک اجرا کنید.
- فقط یک متغیر Performance را عوض کنید.
- Rollback را پیش از Deployment بنویسید.
- Plan و Runtime را در چند بازه بررسی کنید.
- اگر نتیجه مبهم است تغییر را دائمی نکنید.
سناریوی عملی TSQL_SCALAR_UDF_INLINING سه بخش دارد: Baseline، تغییر کنترلشده و تصمیم بر اساس Measure. حذف هر کدام کیفیت تصمیم را پایین میآورد.
سؤالات متداول
TSQL_SCALAR_UDF_INLINING دقیقاً چه مشکلی را هدف میگیرد؟
برای تبدیل برخی Scalar UDFهای واجد شرایط به عبارت Relational داخل Query برای حذف سربار فراخوانی ردیفبهردیف طراحی شده است. ارزش آن زمانی روشن میشود که قبل از تغییر Baseline داشته باشید و اثر را روی Workload واقعی بسنجید.
مقدار فعلی TSQL_SCALAR_UDF_INLINING را چگونه ببینیم؟
از sys.database_scoped_configurations شروع کنید و خروجی را کنار نسخه Engine، Compatibility Level و وضعیت Query Store ثبت کنید.
آیا TSQL_SCALAR_UDF_INLINING همیشه SQL Server را سریعتر میکند؟
خیر. همه UDFها Inline نمیشوند و تغییر Plan میتواند Memory Grant یا Join Order را عوض کند. بنابراین CPU، Duration، Reads و Metric مرتبط با Feature باید قبل و بعد مقایسه شوند.
چه سناریوی تجاری برای TSQL_SCALAR_UDF_INLINING مناسب است؟
نمونه روشن: گزارشی که Scalar UDF محاسبه تخفیف را برای صدها هزار ردیف صدا میزند. در پروژه واقعی Change Window، Rollback و معیار موفقیت را قبل از تغییر تعریف کنید.
TSQL_SCALAR_UDF_INLINING چه تفاوتی با تنظیم سراسری دارد؟
Database Scoped Configuration دامنه اثر را محدودتر میکند و برای Instanceهای چند Workload کنترل دقیقتری میدهد؛ با این حال Hintهای Query و تنظیمات دیگر ممکن است رفتار نهایی را تغییر دهند.
برای پیادهسازی حرفهای TSQL_SCALAR_UDF_INLINING چه کاری لازم است؟
بررسی Query Store، Execution Plan، Baseline، تست بار و Rollback. آموزش و مشاوره زمانی مفید است که تصمیم بر اساس داده همان سامانه گرفته شود.
رایجترین خطا درباره TSQL_SCALAR_UDF_INLINING چیست؟
فرضکردن اینکه هر Scalar UDF با روشنشدن گزینه حتماً Inline میشود. این کار اغلب یک درمان موقت را به سیاست دائمی تبدیل میکند.
اثر Performance TSQL_SCALAR_UDF_INLINING را چگونه بسنجیم؟
بازههای همسطح را مقایسه کنید و CPU، Duration، Reads و Metric تخصصی Feature را بسنجید. Query Store برای Plan Regression بسیار مفید است.
Best Practice تغییر TSQL_SCALAR_UDF_INLINING چیست؟
تغییر را کوچک، مستند و قابل برگشت نگه دارید؛ فقط یک متغیر Performance را در هر آزمایش عوض کنید و نتیجه را چند بار بسنجید.
TSQL_SCALAR_UDF_INLINING با چه نسخههایی سازگار است؟
Scalar UDF Inlining از SQL Server 2019 و Compatibility Level 150 یکی از قابلیتهای Intelligent Query Processing است. مستندات همان نسخه و Compatibility Level محیط خود را ملاک نهایی قرار دهید.
سؤالات مصاحبه
- چرا برای TSQL_SCALAR_UDF_INLINING Baseline لازم است؟
- اگر بعد از تغییر TSQL_SCALAR_UDF_INLINING یک Query بهتر و چند Query بدتر شوند چه میکنید؟
- Query Store در ارزیابی Scalar UDF Inlining در T-SQL چه نقشی دارد؟
- چطور مشکل Statistics را از اثر TSQL_SCALAR_UDF_INLINING جدا میکنید؟
- Rollback شما برای TSQL_SCALAR_UDF_INLINING در Production چیست؟
چکلیست نهایی
- مقدار فعلی TSQL_SCALAR_UDF_INLINING ثبت شده است.
- Baseline مشخص است.
- نسخه و Compatibility Level کنترل شدهاند.
- معیار موفقیت و شکست نوشته شدهاند.
- Rollback آماده است.
- Query Store و Planهای مهم بعد از تغییر بررسی میشوند.
جمعبندی
Scalar UDF Inlining در T-SQL زمانی مفید است که با مسئله واقعی و قابل اندازهگیری استفاده شود. تبدیل برخی Scalar UDFهای واجد شرایط به عبارت Relational داخل Query برای حذف سربار فراخوانی ردیفبهردیف. بهجای تغییر بر اساس توصیه عمومی، Workload خودتان را بسنجید و تغییر را قابل برگشت نگه دارید.
برای مقایسه این گزینه با سایر اعضای همین خانواده به مقاله مادر تنظیمات Performance در سطح Database برگردید.
خدمات برنامهنویسی و پایگاه داده
برنامهنویسی در اصفهان؛ قبول سفارشهای برنامهنویسی و پایگاه داده: 09131253620. انجام پروژه، آموزش برنامهنویسی و آموزش پایگاه داده SQL Server برای پروژههای آموزشی، سازمانی و تجاری.
مجموعهای معتبر با سابقه فعالیت حرفهای از سال ۱۳۷۵ شمسی
از سال ۱۳۷۵ شمسی تاکنون در زمینه طراحی و اجرای پروژههای برنامهنویسی، پایگاه داده، سیستمهای تحت وب، وبسایت و راهکارهای نرمافزاری فعالیت میکنیم.
برای سفارش پروژههای برنامهنویسی و پایگاه داده، سیستمهای تحت وب، وبسایت و راهکارهای نرمافزاری جدید با شماره 09131253620 تماس حاصل فرمایید.
ایتا، واتساپ و تماس مستقیم: +989131253620
تماس با ما