مثالهای عملی مستقل و قابل اجرا
مثال 1: بررسی Unique بودن ایندکس
در این سناریو میخواهیم بررسی Unique بودن ایندکس را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
DECLARE @Obj int = OBJECT_ID(N'dbo.tblNewsContent');
SELECT INDEXPROPERTY(@Obj, N'PK_tblNewsContent', 'IsUnique') AS IsUnique;
| فیلد یا ستون | خروجی نمونه |
|---|
| IsUnique | 1 |
نکته کاربردی این مثال: نام واقعی ایندکس را از sys.indexes بگیرید. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
مثال 2: خواندن ویژگی نخستین ایندکس واقعی جدول
در این سناریو میخواهیم خواندن ویژگی نخستین ایندکس واقعی جدول را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
DECLARE @Obj int=OBJECT_ID(N'dbo.tblNewsContent');
DECLARE @IndexName sysname=(SELECT TOP (1) name FROM sys.indexes WHERE object_id=@Obj AND index_id>0 ORDER BY index_id);
SELECT @IndexName AS IndexName,INDEXPROPERTY(@Obj,@IndexName,'IsUnique') AS IsUnique;
| فیلد یا ستون | خروجی نمونه |
|---|
| IndexName | PK_tblNewsContent |
| IsUnique | 1 |
نکته کاربردی این مثال: نام ایندکس از کاتالوگ خوانده میشود و Hard-code نشده است. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
مثال 3: نمایش چند ویژگی در SELECT
در این سناریو میخواهیم نمایش چند ویژگی در SELECT را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
DECLARE @Obj int = OBJECT_ID(N'dbo.tblNewsContent');
SELECT i.name,
INDEXPROPERTY(@Obj, i.name, 'IsUnique') AS IsUnique,
INDEXPROPERTY(@Obj, i.name, 'IsClustered') AS IsClustered
FROM sys.indexes AS i WHERE i.object_id=@Obj AND i.index_id>0;
| فیلد یا ستون | خروجی نمونه |
|---|
| name | PK_tblNewsContent |
| IsUnique | 1 |
| IsClustered | 1 |
نکته کاربردی این مثال: شرط ایندکس Heap را از گزارش کنار میگذارد. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
مثال 4: فیلتر ایندکسهای Unique
در این سناریو میخواهیم فیلتر ایندکسهای Unique را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
DECLARE @Obj int = OBJECT_ID(N'dbo.tblNewsContent');
SELECT name FROM sys.indexes
WHERE object_id=@Obj AND index_id>0
AND INDEXPROPERTY(@Obj, name, 'IsUnique')=1;
| فیلد یا ستون | خروجی نمونه |
|---|
| name | PK_tblNewsContent |
نکته کاربردی این مثال: ستون is_unique در sys.indexes نیز مستقیم در دسترس است. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
مثال 5: ترکیب با OBJECT_ID و IndexID
در این سناریو میخواهیم ترکیب با OBJECT_ID و IndexID را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
DECLARE @Obj int = OBJECT_ID(N'dbo.tblNewsContent');
SELECT INDEXPROPERTY(@Obj, N'PK_tblNewsContent', 'IndexID') AS IndexId;
| فیلد یا ستون | خروجی نمونه |
|---|
| IndexId | 1 |
نکته کاربردی این مثال: IndexID برای اتصال به sys.index_columns کاربرد دارد. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
مثال 6: مدیریت نام ایندکس ناموجود
در این سناریو میخواهیم مدیریت نام ایندکس ناموجود را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
SELECT INDEXPROPERTY(OBJECT_ID(N'dbo.tblNewsContent'), N'NoSuchIndex', 'IsUnique') AS Result;
| فیلد یا ستون | خروجی نمونه |
|---|
| Result | NULL |
نکته کاربردی این مثال: NULL را معادل غیر Unique ندانید. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
مثال 7: Property نامعتبر
در این سناریو میخواهیم Property نامعتبر را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
SELECT INDEXPROPERTY(OBJECT_ID(N'dbo.tblNewsContent'), N'PK_tblNewsContent', 'NoSuchProperty') AS Result;
| فیلد یا ستون | خروجی نمونه |
|---|
| Result | NULL |
نکته کاربردی این مثال: نام property باید از فهرست پشتیبانیشده انتخاب شود. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
مثال 8: ممیزی ایندکسهای غیرفعال
در این سناریو میخواهیم ممیزی ایندکسهای غیرفعال را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
SELECT OBJECT_SCHEMA_NAME(i.object_id) AS SchemaName, OBJECT_NAME(i.object_id) AS TableName, i.name
FROM sys.indexes AS i
WHERE i.index_id>0 AND INDEXPROPERTY(i.object_id, i.name, 'IsDisabled')=1;
| فیلد یا ستون | خروجی نمونه |
|---|
| SchemaName | Sales |
| TableName | Archive |
| name | IX_Archive_Date |
نکته کاربردی این مثال: فعالسازی ایندکس باید پس از تحلیل علت غیرفعال شدن باشد. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
مثال 9: روش اشتباه و مدیریت سهحالته
در این سناریو میخواهیم روش اشتباه و مدیریت سهحالته را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
DECLARE @P int=INDEXPROPERTY(OBJECT_ID(N'dbo.tblNewsContent'),N'NoSuchIndex','IsUnique');
SELECT CASE WHEN @P=1 THEN N'Unique' WHEN @P=0 THEN N'Non-unique' ELSE N'Unknown' END AS State;
| فیلد یا ستون | خروجی نمونه |
|---|
| State | Unknown |
نکته کاربردی این مثال: حالت ناشناخته را جداگانه گزارش کنید. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
مثال 10: گزارش کاراتر از sys.indexes
در این سناریو میخواهیم گزارش کاراتر از sys.indexes را با تابع INDEXPROPERTY پیادهسازی کنیم. Query زیر مستقل طراحی شده است؛ اگر به جدول پروژه اشاره دارد، نام Schema و شیء را با ساختار واقعی محیط خود هماهنگ کنید و پیش از اجرای عملیاتی سطح دسترسی را کنترل نمایید.
SELECT name, is_unique, type_desc, is_disabled
FROM sys.indexes
WHERE object_id=OBJECT_ID(N'dbo.tblNewsContent') AND index_id>0;
| فیلد یا ستون | خروجی نمونه |
|---|
| name | PK_tblNewsContent |
| is_unique | 1 |
| type_desc | CLUSTERED |
| is_disabled | 0 |
نکته کاربردی این مثال: برای فهرست انبوه، ستونهای کاتالوگ از تابع تکراری مناسبترند. نتیجه نمایشدادهشده نمونه است و شناسهها، نامها یا اندازهها ممکن است در سرور شما متفاوت باشند؛ معیار صحت، منطق Query و متادیتای واقعی محیط است.
سؤالات متداول اختصاصی
۱. تابع INDEXPROPERTY دقیقاً چه مسئلهای را حل میکند؟
INDEXPROPERTY برای خواندن ویژگی عددی یک ایندکس یا آمار مشخص به کار میرود. مزیت آن این است که بهجای حدسزدن یا Hard-code کردن شناسهها و نامها، پاسخ را از متادیتای همان Context دریافت میکنیم. در یک سامانه حرفهای، خروجی باید همراه با کنترل NULL و ثبت Context مصرف شود تا نتیجه قابل اعتماد و قابل عیبیابی باشد.
۲. برای شروع استفاده از INDEXPROPERTY چه پیشنیازی لازم است؟
کاربر باید در پایگاه داده درست متصل باشد، ورودی معتبر بدهد و اجازه مشاهده متادیتای شیء هدف را داشته باشد. بهتر است ابتدا نمونه ساده مقاله اجرا شود و سپس Query با نامهای واقعی Schema و اشیای سازمان جایگزین گردد. برای رشتههای فارسی نیز پیشوند N باید حفظ شود.
۳. آیا آموزش و پیادهسازی سازمانی INDEXPROPERTY ارزش تجاری دارد؟
بله؛ استفاده صحیح از متادیتا زمان توسعه ابزارهای گزارشگیری، مهاجرت، ممیزی و نگهداری را کم میکند و خطای انسانی ناشی از مقادیر ثابت را کاهش میدهد. در دوره آموزشی یا مشاوره SQL Server میتوان این تابع را در قالب یک چارچوب Metadata-driven واقعی، همراه با تست و کنترل مجوزها، پیادهسازی کرد.
۴. INDEXPROPERTY چگونه هزینه پروژههای پایگاه داده را کاهش میدهد؟
وقتی قواعد کشف Schema یکبار و درست نوشته شوند، همان کد در چند محیط و چند نسخه پایگاه داده قابل استفاده است. این کار دوبارهکاری در Deployment و گزارشسازی را کم میکند. البته صرف استفاده از تابع کافی نیست و باید قرارداد نامگذاری، ثبت خطا و آزمون تغییرات نیز در پروژه تعریف شود.
۵. تفاوت استفاده از INDEXPROPERTY با خواندن مستقیم نماهای sys چیست؟
INDEXPROPERTY برای دریافت یک ویژگی یا تبدیل مشخص، کوتاه و خواناست؛ در مقابل، نماهای کاتالوگ sys برای گزارش انبوه، فیلتر چندویژگی و Joinهای تحلیلی انعطاف بیشتری دارند. انتخاب درست به حجم داده، نیاز به جزئیات و شکل Plan بستگی دارد و در بسیاری از ابزارها هر دو روش کنار هم استفاده میشوند.
۶. آیا میتوان برای طراحی ابزار یا گزارش اختصاصی INDEXPROPERTY مشاوره گرفت؟
بله؛ در یک خدمت تحلیل یا اجرای پروژه SQL Server ابتدا سناریو، مجوزها، نسخه موتور و اندازه کاتالوگ بررسی میشود. سپس Queryهای متادیتا با خروجی پایدار، لاگ خطا، تست خودکار و مستندات تحویل داده میشوند تا ابزار به یک نمونه نمایشی محدود نماند.
۷. رایجترین خطای INDEXPROPERTY چیست؟
رایجترین خطا تفسیر NULL بهعنوان پاسخ منفی قطعی است؛ درحالیکه NULL ممکن است از ورودی نامعتبر، Context اشتباه یا نبود مجوز مشاهده متادیتا ناشی شود. خطای دیگر استفاده از نام بدون Schema یا فرض ثابت بودن شناسهها میان پایگاههای داده است. نام یا property نامعتبر و نبود مجوز میتواند NULL بدهد؛ بعضی propertyها فقط برای Index یا فقط برای Statistics معنا دارند.
۸. اجرای INDEXPROPERTY چه اثری بر Performance دارد؟
یک فراخوانی منفرد معمولاً بسیار سبک است، اما اجرای تابع برای هر ردیف یک مجموعه بزرگ یا در شرطی که Join مستقیم کاتالوگ مناسبتر است میتواند هزینه اضافی بسازد. مقدارهای ثابت را یکبار در متغیر محاسبه کنید، Actual Execution Plan و STATISTICS IO را بررسی کنید و برای گزارشهای انبوه از نماهای sys استفاده آگاهانه داشته باشید.
۹. Best Practice اصلی برای INDEXPROPERTY چیست؟
Context را صریح نگه دارید، نامها را Schema-qualified بنویسید، ورودی و خروجی NULL را کنترل کنید و شناسههای متادیتا را در محیط دیگر Hard-code نکنید. همچنین اگر خروجی وارد SQL پویا میشود، نام اشیا را با QUOTENAME محصور کنید و مقدارهای داده را پارامتری نگه دارید.
۱۰. INDEXPROPERTY با کدام نسخههای SQL Server سازگار است؟
این تابع از توابع جاافتاده Transact-SQL است، اما دامنه propertyها، مجوزهای لازم و سطح پشتیبانی در SQL Server، Azure SQL Database، Managed Instance و سرویسهای تحلیلی میتواند متفاوت باشد. پیش از استقرار، مستندات نسخه هدف و Compatibility Level را بررسی و Query را در محیط آزمایشی همان پلتفرم اجرا کنید.