راهنمای جامع Table و Index Hints در SQL Server
Table Hint و Index Hint در SQL Server ابزارهایی برای جهتدهی محدود به Query Optimizer، Storage Engine و Lock Manager هستند. این ابزارها میتوانند مسیر دسترسی به ایندکس، Granularity قفل، Isolation semantics یا شیوه واکنش به Blocking را تغییر دهند. قدرت آنها دقیقاً همان چیزی است که استفاده بیدلیل را خطرناک میکند: Hint ممکن است یک Plan امروز را سریع کند اما انعطاف Optimizer را برای داده فردا کاهش دهد.
این راهنما ۱۷ Hint مهم را در یک نقشه فنی واحد بررسی میکند. هر مورد یک مقاله مستقل با حداقل ده سناریوی عملی دارد. لینکها مستقیم و Root-relative هستند تا وابستگی به دامنه ایجاد نشود. در طراحی نمودارها نیز بهجای تصویر تزئینی، مسیر واقعی Parse، Optimization، Plan Operator، Lock Manager، Storage Access و Result نمایش داده شده است.
دسترسی سریع به مقالههای مستقل
نمودار معماری: TABLE_AND_INDEX_HINTS در کدام مرحله از بهینهسازی و اجرای Query اثر میگذارد.
دستهبندی منطقی Hintها
گروه اول Hintهای Access Path هستند: INDEX، FORCESEEK، FORCESCAN و NOEXPAND. اینها مستقیماً روی نحوه دسترسی به ساختار ذخیرهسازی یا Indexed View اثر میگذارند. گروه دوم Hintهای Lock Granularity و Lock Mode شامل ROWLOCK، PAGLOCK، TABLOCK، TABLOCKX، UPDLOCK، XLOCK و HOLDLOCK هستند. گروه سوم Hintهای Blocking و Isolation شامل READPAST، NOWAIT، READCOMMITTED، READCOMMITTEDLOCK، READUNCOMMITTED و SNAPSHOT است.
در سطح داخلی، Query ابتدا Parse و Bind میشود، سپس Optimizer فضای Planهای قانونی را بررسی میکند. Access-path Hintها میتوانند بخشی از این فضا را حذف کنند. Locking Hintها بیشتر هنگام اجرا و دسترسی به Row/Page/Table اثر خود را نشان میدهند. Isolation Hintها نیز تعیین میکنند Reader از Lock، Version Store یا semantics خاص جدول Memory-Optimized چگونه استفاده کند.
| Hint | کاربرد اصلی | خروجی یا نکته مهم | لینک آموزش کامل |
|---|
| INDEX | وادار کردن Optimizer به بررسی و استفاده از ایندکس مشخص | Index Seek / Index Scan روی ایندکس نامبرده | آموزش کامل INDEX |
| FORCESEEK | محدود کردن مسیرهای دسترسی به عملیات Seek روی ایندکسهای مجاز | Index Seek بهجای Scan در صورت امکان قانونی | آموزش کامل FORCESEEK |
| FORCESCAN | وادار کردن Optimizer به استفاده از Scan بهجای Seek | Index Scan یا Table Scan پس از Partition Elimination | آموزش کامل FORCESCAN |
| NOEXPAND | وادار کردن Query Optimizer به استفاده مستقیم از Indexed View بهعنوان ساختار مادیشده | دسترسی به ایندکسهای View بهجای Expand شدن تعریف View | آموزش کامل NOEXPAND |
| ROWLOCK | درخواست اولویت Lock در سطح Row یا Key | قفلهای ریزدانهتر روی Key/Row در صورت امکان | آموزش کامل ROWLOCK |
| PAGLOCK | درخواست استفاده از Page Lock در نقاطی که Lock Engine اجازه میدهد | قفلگذاری در سطح Page بهجای Row/Key | آموزش کامل PAGLOCK |
| TABLOCK | درخواست Lock در سطح کل Table برای عملیات مربوط به همان Reference | Table-level Shared/Intent lock متناسب با نوع عملیات | آموزش کامل TABLOCK |
| TABLOCKX | گرفتن Exclusive Lock روی کل Table | X Lock در سطح Table تا پایان محدوده نگهداری Lock | آموزش کامل TABLOCKX |
| UPDLOCK | گرفتن Update Lock هنگام خواندن و نگهداری آن تا پایان Transaction | U Lock روی Row/Keyهای خواندهشده و تبدیل بعدی به X | آموزش کامل UPDLOCK |
| XLOCK | درخواست Exclusive Lock روی منابع دادهای لمسشده | X Lock روی Row/Page/Table مطابق Granularity نهایی | آموزش کامل XLOCK |
| HOLDLOCK | اعمال رفتار معادل SERIALIZABLE برای Reference جدول | نگهداری Shared/Range Lock تا انتهای Transaction | آموزش کامل HOLDLOCK |
| READPAST | رد شدن از Rowهای قفلشده بهجای انتظار برای آزاد شدن آنها | Skip کردن Row-level Lockهای ناسازگار | آموزش کامل READPAST |
| NOWAIT | بازگشت فوری خطا در مواجهه با Lock ناسازگار بهجای انتظار | Lock request با Timeout صفر برای همان Table Reference | آموزش کامل NOWAIT |
| READCOMMITTED | اجرای دسترسی با semantics سطح READ COMMITTED برای همان Reference | Shared Lock یا Row Versioning بسته به READ_COMMITTED_SNAPSHOT | آموزش کامل READCOMMITTED |
| READCOMMITTEDLOCK | وادار کردن READ COMMITTED به استفاده از Shared Lock بهجای Versioning | S Lock روی داده خواندهشده حتی وقتی RCSI فعال است | آموزش کامل READCOMMITTEDLOCK |
| READUNCOMMITTED | اجازه خواندن داده Commit نشده با حداقل قفل دادهای | Dirty Read و عدم گرفتن Shared Data Lock معمول | آموزش کامل READUNCOMMITTED |
| SNAPSHOT | خواندن Snapshot-consistent برای جدول Memory-Optimized در محدوده پشتیبانیشده | نسخه سازگار از Rowهای In-Memory بر اساس timestamp تراکنش | آموزش کامل SNAPSHOT |
نمودار جریان اجرای واقعی: از ورود T-SQL تا Plan، دسترسی به داده و خروجی هنگام استفاده از TABLE_AND_INDEX_HINTS.
معرفی همه Hintها
INDEX در SQL Server
وادار کردن Optimizer به بررسی و استفاده از ایندکس مشخص. در Plan یا رفتار Runtime معمولاً باید Index Seek / Index Scan روی ایندکس نامبرده را بررسی کنید. مزیت بالقوه آن کنترل مسیر دسترسی برای عیبیابی یا شرایط بسیار خاص است، اما ممکن است با تغییر توزیع داده، همان ایندکس انتخاب ضعیفی شود. آموزش کامل INDEX با مثالهای عملی و نمودار اجرای واقعی
FORCESEEK در SQL Server
محدود کردن مسیرهای دسترسی به عملیات Seek روی ایندکسهای مجاز. در Plan یا رفتار Runtime معمولاً باید Index Seek بهجای Scan در صورت امکان قانونی را بررسی کنید. مزیت بالقوه آن کاهش خواندن صفحات در Predicateهای انتخابپذیر است، اما ممکن است خطای نبود Plan مناسب یا Plan ضعیف در بازههای بزرگ ایجاد کند. آموزش کامل FORCESEEK با مثالهای عملی و نمودار اجرای واقعی
FORCESCAN در SQL Server
وادار کردن Optimizer به استفاده از Scan بهجای Seek. در Plan یا رفتار Runtime معمولاً باید Index Scan یا Table Scan پس از Partition Elimination را بررسی کنید. مزیت بالقوه آن مفید وقتی برآورد کم باعث Seek + Lookup پرهزینه شده است است، اما برای Queryهای بسیار انتخابپذیر میتواند I/O را شدیداً بالا ببرد. آموزش کامل FORCESCAN با مثالهای عملی و نمودار اجرای واقعی
NOEXPAND در SQL Server
وادار کردن Query Optimizer به استفاده مستقیم از Indexed View بهعنوان ساختار مادیشده. در Plan یا رفتار Runtime معمولاً باید دسترسی به ایندکسهای View بهجای Expand شدن تعریف View را بررسی کنید. مزیت بالقوه آن استفاده قابل پیشبینی از محاسبات ازپیشتجمیعشده است، اما نیازمند Indexed View معتبر و SET optionهای لازم است. آموزش کامل NOEXPAND با مثالهای عملی و نمودار اجرای واقعی
ROWLOCK در SQL Server
درخواست اولویت Lock در سطح Row یا Key. در Plan یا رفتار Runtime معمولاً باید قفلهای ریزدانهتر روی Key/Row در صورت امکان را بررسی کنید. مزیت بالقوه آن کاهش دامنه Blocking در برخی تراکنشهای کوتاه است، اما تضمین نمیکند Lock Escalation رخ ندهد و تعداد Lock زیاد هزینه حافظه دارد. آموزش کامل ROWLOCK با مثالهای عملی و نمودار اجرای واقعی
PAGLOCK در SQL Server
درخواست استفاده از Page Lock در نقاطی که Lock Engine اجازه میدهد. در Plan یا رفتار Runtime معمولاً باید قفلگذاری در سطح Page بهجای Row/Key را بررسی کنید. مزیت بالقوه آن کاهش تعداد Lockها برای عملیات متراکم روی صفحات محدود است، اما ممکن است دامنه Blocking را از چند Row به کل Page گسترش دهد. آموزش کامل PAGLOCK با مثالهای عملی و نمودار اجرای واقعی
TABLOCK در SQL Server
درخواست Lock در سطح کل Table برای عملیات مربوط به همان Reference. در Plan یا رفتار Runtime معمولاً باید Table-level Shared/Intent lock متناسب با نوع عملیات را بررسی کنید. مزیت بالقوه آن کاهش سربار تعداد Lock و گاهی کمک به الگوهای Bulk خاص است، اما Concurrency را کاهش میدهد و میتواند کاربران بیشتری را Block کند. آموزش کامل TABLOCK با مثالهای عملی و نمودار اجرای واقعی
TABLOCKX در SQL Server
گرفتن Exclusive Lock روی کل Table. در Plan یا رفتار Runtime معمولاً باید X Lock در سطح Table تا پایان محدوده نگهداری Lock را بررسی کنید. مزیت بالقوه آن ایزولهسازی کامل جدول برای عملیات حساس و کوتاه است، اما خواندن/نوشتن همزمان دیگر Sessionها را بهشدت محدود میکند. آموزش کامل TABLOCKX با مثالهای عملی و نمودار اجرای واقعی
UPDLOCK در SQL Server
گرفتن Update Lock هنگام خواندن و نگهداری آن تا پایان Transaction. در Plan یا رفتار Runtime معمولاً باید U Lock روی Row/Keyهای خواندهشده و تبدیل بعدی به X را بررسی کنید. مزیت بالقوه آن کاهش Race Condition در الگوی Read-Then-Update است، اما Transaction طولانی میتواند Blocking ایجاد کند. آموزش کامل UPDLOCK با مثالهای عملی و نمودار اجرای واقعی
XLOCK در SQL Server
درخواست Exclusive Lock روی منابع دادهای لمسشده. در Plan یا رفتار Runtime معمولاً باید X Lock روی Row/Page/Table مطابق Granularity نهایی را بررسی کنید. مزیت بالقوه آن جلوگیری قطعی از دسترسی ناسازگار به داده حساس در Transaction است، اما شدت Blocking بالا و ریسک کاهش Throughput. آموزش کامل XLOCK با مثالهای عملی و نمودار اجرای واقعی
HOLDLOCK در SQL Server
اعمال رفتار معادل SERIALIZABLE برای Reference جدول. در Plan یا رفتار Runtime معمولاً باید نگهداری Shared/Range Lock تا انتهای Transaction را بررسی کنید. مزیت بالقوه آن جلوگیری از Phantom در بازههای خواندهشده است، اما Range Lockها میتوانند همزمانی Insert/Update را محدود کنند. آموزش کامل HOLDLOCK با مثالهای عملی و نمودار اجرای واقعی
READPAST در SQL Server
رد شدن از Rowهای قفلشده بهجای انتظار برای آزاد شدن آنها. در Plan یا رفتار Runtime معمولاً باید Skip کردن Row-level Lockهای ناسازگار را بررسی کنید. مزیت بالقوه آن مناسب الگوی Queue Reader برای برداشتن کارهای آزاد است، اما Page Lockها را رد نمیکند و تحت RCSI محدودیتهای مهم دارد. آموزش کامل READPAST با مثالهای عملی و نمودار اجرای واقعی
NOWAIT در SQL Server
بازگشت فوری خطا در مواجهه با Lock ناسازگار بهجای انتظار. در Plan یا رفتار Runtime معمولاً باید Lock request با Timeout صفر برای همان Table Reference را بررسی کنید. مزیت بالقوه آن مناسب Fail-Fast و Retry کنترلشده در لایه برنامه است، اما با TABLOCK رفتار مورد انتظار ندارد و باید LOCK_TIMEOUT 0 را سنجید. آموزش کامل NOWAIT با مثالهای عملی و نمودار اجرای واقعی
READCOMMITTED در SQL Server
اجرای دسترسی با semantics سطح READ COMMITTED برای همان Reference. در Plan یا رفتار Runtime معمولاً باید Shared Lock یا Row Versioning بسته به READ_COMMITTED_SNAPSHOT را بررسی کنید. مزیت بالقوه آن بیان صریح رفتار پیشفرض خواندن متعهدشده است، اما تحت RCSI ممکن است تصور قفلمحور بودن اشتباه باشد. آموزش کامل READCOMMITTED با مثالهای عملی و نمودار اجرای واقعی
READCOMMITTEDLOCK در SQL Server
وادار کردن READ COMMITTED به استفاده از Shared Lock بهجای Versioning. در Plan یا رفتار Runtime معمولاً باید S Lock روی داده خواندهشده حتی وقتی RCSI فعال است را بررسی کنید. مزیت بالقوه آن وقتی همگامسازی قفلمحور برای منطق خاص لازم است است، اما میتواند Blocking را نسبت به Row Versioning افزایش دهد. آموزش کامل READCOMMITTEDLOCK با مثالهای عملی و نمودار اجرای واقعی
READUNCOMMITTED در SQL Server
اجازه خواندن داده Commit نشده با حداقل قفل دادهای. در Plan یا رفتار Runtime معمولاً باید Dirty Read و عدم گرفتن Shared Data Lock معمول را بررسی کنید. مزیت بالقوه آن کاهش انتظار در گزارشهای کماهمیت از نظر سازگاری است، اما Dirty/Nonrepeatable/Phantom read و حتی نتایج منطقی ناپایدار؛ Sch-S همچنان وجود دارد. آموزش کامل READUNCOMMITTED با مثالهای عملی و نمودار اجرای واقعی
SNAPSHOT در SQL Server
خواندن Snapshot-consistent برای جدول Memory-Optimized در محدوده پشتیبانیشده. در Plan یا رفتار Runtime معمولاً باید نسخه سازگار از Rowهای In-Memory بر اساس timestamp تراکنش را بررسی کنید. مزیت بالقوه آن خواندن غیرمسدودکننده سازگار در In-Memory OLTP است، اما این Table Hint مخصوص Memory-Optimized Table است و روی جدول Disk-based عمومی نیست. آموزش کامل SNAPSHOT با مثالهای عملی و نمودار اجرای واقعی
شش مثال ترکیبی برای درک رفتار Hintها
مثال 1: FORCESEEK برای Predicate انتخابپذیر
این Query برای مشاهده رفتار Hint در یک سناریوی کوچک طراحی شده است. در Production باید همین منطق روی داده نماینده و با Actual Execution Plan، STATISTICS IO و تست همزمانی تکرار شود.
IF OBJECT_ID('tempdb..#HintDemo') IS NOT NULL DROP TABLE #HintDemo;
CREATE TABLE #HintDemo
(
OrderID int NOT NULL PRIMARY KEY,
CustomerID int NOT NULL,
Status nvarchar(20) NOT NULL,
Amount decimal(12,2) NOT NULL,
CreatedAt datetime2(0) NOT NULL
);
CREATE INDEX IX_HintDemo_Status ON #HintDemo(Status) INCLUDE (Amount, CustomerID);
INSERT INTO #HintDemo(OrderID,CustomerID,Status,Amount,CreatedAt)
VALUES
(1,10,N'New',120.00,'2026-07-20'),
(2,10,N'Paid',850.00,'2026-07-20'),
(3,20,N'New',95.00,'2026-07-21'),
(4,30,N'Paid',440.00,'2026-07-22'),
(5,40,N'Cancelled',50.00,'2026-07-22');
SELECT OrderID,Amount FROM #HintDemo WITH (FORCESEEK) WHERE Status=N'Paid';
DROP TABLE #HintDemo;
| مشاهده | خروجی نمونه |
|---|
| Operator | Index Seek |
| تأیید | Plan/Lock باید با ابزارهای Runtime بررسی شود |
نکته: نتیجه دادهای تنها بخشی از ارزیابی است؛ هدف Hint معمولاً در Plan یا Lock behavior دیده میشود.
مثال 2: FORCESCAN برای مقایسه با Seek
این Query برای مشاهده رفتار Hint در یک سناریوی کوچک طراحی شده است. در Production باید همین منطق روی داده نماینده و با Actual Execution Plan، STATISTICS IO و تست همزمانی تکرار شود.
IF OBJECT_ID('tempdb..#HintDemo') IS NOT NULL DROP TABLE #HintDemo;
CREATE TABLE #HintDemo
(
OrderID int NOT NULL PRIMARY KEY,
CustomerID int NOT NULL,
Status nvarchar(20) NOT NULL,
Amount decimal(12,2) NOT NULL,
CreatedAt datetime2(0) NOT NULL
);
CREATE INDEX IX_HintDemo_Status ON #HintDemo(Status) INCLUDE (Amount, CustomerID);
INSERT INTO #HintDemo(OrderID,CustomerID,Status,Amount,CreatedAt)
VALUES
(1,10,N'New',120.00,'2026-07-20'),
(2,10,N'Paid',850.00,'2026-07-20'),
(3,20,N'New',95.00,'2026-07-21'),
(4,30,N'Paid',440.00,'2026-07-22'),
(5,40,N'Cancelled',50.00,'2026-07-22');
SELECT SUM(Amount) FROM #HintDemo WITH (FORCESCAN);
DROP TABLE #HintDemo;
| مشاهده | خروجی نمونه |
|---|
| Operator | Scan |
| تأیید | Plan/Lock باید با ابزارهای Runtime بررسی شود |
نکته: نتیجه دادهای تنها بخشی از ارزیابی است؛ هدف Hint معمولاً در Plan یا Lock behavior دیده میشود.
مثال 3: UPDLOCK در الگوی Read-Then-Update
این Query برای مشاهده رفتار Hint در یک سناریوی کوچک طراحی شده است. در Production باید همین منطق روی داده نماینده و با Actual Execution Plan، STATISTICS IO و تست همزمانی تکرار شود.
IF OBJECT_ID('tempdb..#HintDemo') IS NOT NULL DROP TABLE #HintDemo;
CREATE TABLE #HintDemo
(
OrderID int NOT NULL PRIMARY KEY,
CustomerID int NOT NULL,
Status nvarchar(20) NOT NULL,
Amount decimal(12,2) NOT NULL,
CreatedAt datetime2(0) NOT NULL
);
CREATE INDEX IX_HintDemo_Status ON #HintDemo(Status) INCLUDE (Amount, CustomerID);
INSERT INTO #HintDemo(OrderID,CustomerID,Status,Amount,CreatedAt)
VALUES
(1,10,N'New',120.00,'2026-07-20'),
(2,10,N'Paid',850.00,'2026-07-20'),
(3,20,N'New',95.00,'2026-07-21'),
(4,30,N'Paid',440.00,'2026-07-22'),
(5,40,N'Cancelled',50.00,'2026-07-22');
BEGIN TRAN; SELECT OrderID FROM #HintDemo WITH (UPDLOCK) WHERE OrderID=1; UPDATE #HintDemo SET Amount=Amount+10 WHERE OrderID=1; COMMIT; DROP TABLE #HintDemo;
| مشاهده | خروجی نمونه |
|---|
| Lock | U سپس X |
| تأیید | Plan/Lock باید با ابزارهای Runtime بررسی شود |
نکته: نتیجه دادهای تنها بخشی از ارزیابی است؛ هدف Hint معمولاً در Plan یا Lock behavior دیده میشود.
مثال 4: READPAST در Queue Reader
این Query برای مشاهده رفتار Hint در یک سناریوی کوچک طراحی شده است. در Production باید همین منطق روی داده نماینده و با Actual Execution Plan، STATISTICS IO و تست همزمانی تکرار شود.
IF OBJECT_ID('tempdb..#HintDemo') IS NOT NULL DROP TABLE #HintDemo;
CREATE TABLE #HintDemo
(
OrderID int NOT NULL PRIMARY KEY,
CustomerID int NOT NULL,
Status nvarchar(20) NOT NULL,
Amount decimal(12,2) NOT NULL,
CreatedAt datetime2(0) NOT NULL
);
CREATE INDEX IX_HintDemo_Status ON #HintDemo(Status) INCLUDE (Amount, CustomerID);
INSERT INTO #HintDemo(OrderID,CustomerID,Status,Amount,CreatedAt)
VALUES
(1,10,N'New',120.00,'2026-07-20'),
(2,10,N'Paid',850.00,'2026-07-20'),
(3,20,N'New',95.00,'2026-07-21'),
(4,30,N'Paid',440.00,'2026-07-22'),
(5,40,N'Cancelled',50.00,'2026-07-22');
SELECT TOP (1) OrderID FROM #HintDemo WITH (READPAST, UPDLOCK, ROWLOCK) WHERE Status=N'New' ORDER BY OrderID;
DROP TABLE #HintDemo;
| مشاهده | خروجی نمونه |
|---|
| رفتار | رد شدن از Row قفلشده |
| تأیید | Plan/Lock باید با ابزارهای Runtime بررسی شود |
نکته: نتیجه دادهای تنها بخشی از ارزیابی است؛ هدف Hint معمولاً در Plan یا Lock behavior دیده میشود.
مثال 5: NOWAIT برای Fail-Fast
این Query برای مشاهده رفتار Hint در یک سناریوی کوچک طراحی شده است. در Production باید همین منطق روی داده نماینده و با Actual Execution Plan، STATISTICS IO و تست همزمانی تکرار شود.
IF OBJECT_ID('tempdb..#HintDemo') IS NOT NULL DROP TABLE #HintDemo;
CREATE TABLE #HintDemo
(
OrderID int NOT NULL PRIMARY KEY,
CustomerID int NOT NULL,
Status nvarchar(20) NOT NULL,
Amount decimal(12,2) NOT NULL,
CreatedAt datetime2(0) NOT NULL
);
CREATE INDEX IX_HintDemo_Status ON #HintDemo(Status) INCLUDE (Amount, CustomerID);
INSERT INTO #HintDemo(OrderID,CustomerID,Status,Amount,CreatedAt)
VALUES
(1,10,N'New',120.00,'2026-07-20'),
(2,10,N'Paid',850.00,'2026-07-20'),
(3,20,N'New',95.00,'2026-07-21'),
(4,30,N'Paid',440.00,'2026-07-22'),
(5,40,N'Cancelled',50.00,'2026-07-22');
SELECT OrderID FROM #HintDemo WITH (NOWAIT) WHERE OrderID=1;
DROP TABLE #HintDemo;
| مشاهده | خروجی نمونه |
|---|
| رفتار | بدون انتظار در Lock conflict |
| تأیید | Plan/Lock باید با ابزارهای Runtime بررسی شود |
نکته: نتیجه دادهای تنها بخشی از ارزیابی است؛ هدف Hint معمولاً در Plan یا Lock behavior دیده میشود.
مثال 6: READUNCOMMITTED و هزینه سازگاری
این Query برای مشاهده رفتار Hint در یک سناریوی کوچک طراحی شده است. در Production باید همین منطق روی داده نماینده و با Actual Execution Plan، STATISTICS IO و تست همزمانی تکرار شود.
IF OBJECT_ID('tempdb..#HintDemo') IS NOT NULL DROP TABLE #HintDemo;
CREATE TABLE #HintDemo
(
OrderID int NOT NULL PRIMARY KEY,
CustomerID int NOT NULL,
Status nvarchar(20) NOT NULL,
Amount decimal(12,2) NOT NULL,
CreatedAt datetime2(0) NOT NULL
);
CREATE INDEX IX_HintDemo_Status ON #HintDemo(Status) INCLUDE (Amount, CustomerID);
INSERT INTO #HintDemo(OrderID,CustomerID,Status,Amount,CreatedAt)
VALUES
(1,10,N'New',120.00,'2026-07-20'),
(2,10,N'Paid',850.00,'2026-07-20'),
(3,20,N'New',95.00,'2026-07-21'),
(4,30,N'Paid',440.00,'2026-07-22'),
(5,40,N'Cancelled',50.00,'2026-07-22');
SELECT COUNT(*) AS Cnt FROM #HintDemo WITH (READUNCOMMITTED);
DROP TABLE #HintDemo;
| مشاهده | خروجی نمونه |
|---|
| Isolation | Dirty read ممکن است |
| تأیید | Plan/Lock باید با ابزارهای Runtime بررسی شود |
نکته: نتیجه دادهای تنها بخشی از ارزیابی است؛ هدف Hint معمولاً در Plan یا Lock behavior دیده میشود.
نمودار تصمیم فنی: مقایسه Plan بدون Hint با سناریوی استفاده از TABLE_AND_INDEX_HINTS و نقاط ریسک Performance/Concurrency.
Performance، خطاها و Best Practice
قاعده طلایی این است که ابتدا علت ریشهای را پیدا کنید. Statistics قدیمی، Predicate غیر SARGable، Missing Index، Parameter Sensitivity، Cardinality Estimate اشتباه، Transaction طولانی یا طراحی Queue ضعیف را نباید با Hint پنهان کرد. Hint زمانی توجیه دارد که مشکل بازتولیدپذیر است، گزینههای کمریسکتر بررسی شدهاند و نتیجه در بار واقعی اندازهگیری شده است.
برای Access Path، Logical Reads، CPU، Duration، Memory Grant و Operatorها را مقایسه کنید. برای Locking، waitهای LCK_M_، Deadlock Graph، طول Transaction و تعداد Lock را بسنجید. برای Isolation، Correctness داده، Versioning overhead و Blocking را همزمان ببینید. Query Store بهترین ابزار برای نگهداری شواهد قبل و بعد از تغییر است.
سؤالات متداول
Table Hint چیست؟
دستور محلی روی Table Reference است که بخشی از رفتار access، locking یا isolation را جهت میدهد.
آیا Hint همیشه Query را سریعتر میکند؟
خیر؛ Hint میتواند Plan بهتر یا بدتر بسازد و باید اندازهگیری شود.
تفاوت FORCESEEK و INDEX چیست؟
INDEX یک ایندکس مشخص را هدف میگیرد، FORCESEEK نوع access را به Seek محدود میکند.
ROWLOCK تضمین میکند فقط Row Lock داشته باشیم؟
خیر؛ Lock escalation و تصمیمهای Lock Manager همچنان مهماند.
READPAST همه Lockها را رد میکند؟
خیر؛ عمدتاً Row-level lockها را رد میکند و Page Lock میتواند مانع شود.
NOWAIT چه کاربردی دارد؟
برای Fail-Fast هنگام Lock conflict و پیادهسازی Retry کنترلشده.
READUNCOMMITTED بدون Lock است؟
خیر؛ Shared data lock معمول را نمیگیرد اما Sch-S و قفلهای ساختاری همچنان مطرحاند.
HOLDLOCK چه معنایی دارد؟
برای همان Table Reference رفتار معادل SERIALIZABLE ایجاد میکند.
SNAPSHOT table hint روی هر جدولی کار میکند؟
خیر؛ این Hint مخصوص Memory-Optimized table در محدوده پشتیبانی SQL Server است.
بهترین روش مدیریت Hint چیست؟
مستندسازی دلیل، تست Regression، Query Store، بازبینی پس از Upgrade و داشتن Rollback plan.
سؤالات مصاحبه
- چه زمانی Hint فضای Planهای Optimizer را محدود میکند؟
- چگونه Access Path Hint را با Locking Hint از نظر اثر داخلی تفکیک میکنید؟
- چه Metricsی برای اثبات مفید بودن Hint لازم است؟
- READPAST چه محدودیتی در برابر Page Lock دارد؟
- چرا SNAPSHOT table hint را نباید با Snapshot Isolation عمومی یکی دانست؟
جمعبندی و مسیر مطالعه
Hintها ابزارهای جراحی دقیق SQL Server هستند. از INDEX و FORCESEEK برای Access Path، از UPDLOCK و HOLDLOCK برای الگوهای تراکنشی، و از READPAST/NOWAIT برای کنترل Blocking فقط زمانی استفاده کنید که رفتار واقعی موتور را اندازهگیری کردهاید. برای جزئیات هر مورد، از فهرست زیر وارد مقاله مستقل همان Hint شوید.
خدمات برنامهنویسی و پایگاه داده
برنامهنویسی در اصفهان
قبول سفارشهای برنامهنویسی و پایگاه داده: 09131253620
انجام پروژههای برنامهنویسی، آموزش برنامهنویسی و آموزش پایگاه داده SQL Server با رویکرد حرفهای و قابل توسعه.
مجموعهای معتبر با سابقه فعالیت حرفهای از سال ۱۳۷۵ شمسی
از سال ۱۳۷۵ شمسی تاکنون در زمینه طراحی و اجرای پروژههای برنامهنویسی، پایگاه داده، سیستمهای تحت وب، وبسایت و راهکارهای نرمافزاری فعالیت میکنیم.
برای سفارش پروژههای برنامهنویسی و پایگاه داده، سیستمهای تحت وب، وبسایت و راهکارهای نرمافزاری جدید، با شماره تلفن همراه 09131253620 تماس حاصل فرمایید.
ایتا، واتساپ و تماس مستقیم: +989131253620
تماس با ما