آموزش CREATE NONCLUSTERED COLUMNSTORE INDEX در SQL Server؛ ساخت ایندکس ستونی غیرخوشه‌ای با ۱۰ مثال عملی

آموزش CREATE NONCLUSTERED COLUMNSTORE INDEX در SQL Server؛ ساخت ایندکس ستونی غیرخوشه‌ای

توسط admin | گروه SQL Server | 1405/04/31

نظرات 0

آموزش CREATE NONCLUSTERED COLUMNSTORE INDEX در SQL Server؛ ساخت ایندکس ستونی غیرخوشه‌ای

مقدمه

CREATE NONCLUSTERED COLUMNSTORE INDEX یکی از دستورهای مهم طراحی و بهینه‌سازی در Microsoft SQL Server است. هدف آن افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است. تعریف درست می‌تواند خواندن منطقی، CPU و زمان پاسخ را کاهش دهد، اما تعریف نامناسب فضای ذخیره‌سازی و هزینه INSERT، UPDATE و DELETE را بالا می‌برد.

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

برای مشاهده نقشه کامل خانواده ایندکس‌ها، ابتدا راهنمای جامع دستورات ساخت ایندکس در SQL Server را مطالعه کنید. این صفحه جایگاه ساخت ایندکس ستونی غیرخوشه‌ای را در کنار Rowstore، Columnstore و ایندکس‌های تخصصی نشان می‌دهد.

تعریف و کاربرد CREATE NONCLUSTERED COLUMNSTORE INDEX

ساخت ایندکس ستونی غیرخوشه‌ای در گروه تحلیل بلادرنگ قرار می‌گیرد. تعریف ایندکس یک تصمیم فیزیکی درباره نحوه دسترسی به داده است؛ موتور پایگاه داده همچنان نتیجه منطقی Query را یکسان نگه می‌دارد، اما مسیر رسیدن به نتیجه می‌تواند از Scan پرهزینه به Seek یا پردازش ستونی هدفمند تغییر کند.

مهم‌ترین کاربرد این دستور، افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است. پیش از اجرا باید مالکیت Schema، مجوز ALTER روی جدول، فضای کافی، سلامت داده و سازگاری گزینه‌ها با نسخه سرور بررسی شود. نام‌گذاری یکنواخت نیز عیب‌یابی، Deployment و نگهداری آینده را ساده‌تر می‌کند.

اصل مهندسی: ایندکس را برای Query واقعی بسازید، نه صرفاً برای ستونی که مهم به نظر می‌رسد. انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها بخشی از معیار پذیرش این تغییر است.

نحو عمومی دستور

CREATE NONCLUSTERED COLUMNSTORE INDEX IX_CREATE_NONCLUSTERED_COLUMNSTORE_INDEX
    ON dbo.OperationalTable(DateColumn, CategoryID, Amount);
    

اجزای مهم تعریف

جزءنقشپرسش کنترلی
نام ایندکسشناسه قابل نگهداری و استقرارآیا الگوی نام‌گذاری تیم رعایت شده است؟
جدول و Schemaهدف فیزیکی ساختارآیا محیط و Schema دقیق انتخاب شده‌اند؟
ستون کلیدیتعیین مسیر جست‌وجو یا سازمان‌دهیآیا ترتیب با Predicate و Sort هماهنگ است؟
گزینه‌های WITHکنترل ساخت، قفل، فضا و نگهداریآیا نسخه و Edition از گزینه پشتیبانی می‌کند؟
اعتبارسنجیاثبات اثر پس از ساختآیا Plan و IO قبل و بعد ثبت شده‌اند؟

پیش‌نیازها و طراحی قبل از اجرا

ابتدا Query Store، Extended Events یا ابزار مانیتورینگ را برای یافتن Queryهای پرهزینه بررسی کنید. تعداد اجرا و اثر تجمعی مهم‌تر از کندی یک اجرای نادر است. سپس Actual Execution Plan را همراه با پارامتر واقعی ذخیره کنید تا مشکل Scan، Lookup، Sort، Hash Spill یا تخمین اشتباه قابل مشاهده باشد.

توزیع داده و Selectivity ستون‌ها را با Statistics و Queryهای شمارشی بررسی کنید. ستونی با چند مقدار تکراری همیشه کلید خوبی نیست، مگر آنکه با فیلتر، ستون دوم یا ساختار تخصصی ترکیب شود. نوع داده کلید نیز بر اندازه صفحه، Fan-out و هزینه حافظه اثر مستقیم دارد.

در مرحله استقرار، مدت ساخت، رشد Transaction Log، فضای آزاد Data File و TempDB، احتمال Blocking و امکان Online Operation را برآورد کنید. برای محیط حساس، اسکریپت بازگشت و معیار توقف باید پیش از شروع تأیید شده باشد.

  • ثبت Query، پارامتر، Plan و شاخص‌های پایه پیش از تغییر
  • بررسی ایندکس‌های موجود و حذف هم‌پوشانی غیرضروری
  • کنترل نوع داده، طول کلید و توزیع مقادیر
  • توجه ویژه به انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها
  • آزمون هم‌زمانی خواندن و نوشتن در محیط مشابه تولید
  • ثبت برنامه استقرار، پایش و بازگشت

مثال‌های عملی

مثال 1: ساخت پایه روی ستون پرتکرار با CREATE NONCLUSTERED COLUMNSTORE INDEX

یک مسیر دسترسی اولیه برای جست‌وجوی پرتکرار ساخته می‌شود و سپس متادیتای آن کنترل می‌گردد. در این مثال، هدف عملی افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است.

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE1', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE1;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE1
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE1
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E1
        ON dbo.DemoNonclusteredColumnstoreE1(CustomerID, ProductID, SaleDate, Quantity, NetAmount);
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE1');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE1
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E1NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: این الگو نقطه شروع است؛ در سامانه واقعی باید انتخاب ستون با Execution Plan و آمار مصرف تأیید شود. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

مثال 2: کلید مرکب برای جست‌وجوی چندشرطی با CREATE NONCLUSTERED COLUMNSTORE INDEX

دو ستون با ترتیب هدفمند در تعریف ایندکس قرار می‌گیرند تا شرط‌های ترکیبی و مرتب‌سازی رایج پوشش داده شوند. در این مثال، هدف عملی افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است.

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE2', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE2;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE2
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE2
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E2
        ON dbo.DemoNonclusteredColumnstoreE2(SaleDate, ProductID, Quantity, NetAmount, RegionID);
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE2');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE2
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E2NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: ستون سمت چپ کلید نقش تعیین‌کننده دارد و تغییر ترتیب ستون‌ها می‌تواند شکل Seek را عوض کند. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

مثال 3: پشتیبانی از مرتب‌سازی نزولی با CREATE NONCLUSTERED COLUMNSTORE INDEX

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

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE3', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE3;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE3
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE3
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E3
        ON dbo.DemoNonclusteredColumnstoreE3(CustomerID, SaleDate, NetAmount, RegionID);
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE3');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE3
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E3NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: جهت کلید زمانی مهم‌تر می‌شود که Query ترکیبی از چند ستون با جهت‌های متفاوت داشته باشد. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

مثال 4: استفاده در شرط و اتصال جدول‌ها با CREATE NONCLUSTERED COLUMNSTORE INDEX

نمونه‌ای نزدیک به گزارش عملی ساخته می‌شود تا نقش ایندکس در Predicate و Join یا بازیابی ردیف‌های هدف دیده شود. در این مثال، هدف عملی افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است.

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE4', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE4;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE4
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE4
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E4
        ON dbo.DemoNonclusteredColumnstoreE4(CustomerID, ProductID, SaleDate, Quantity, NetAmount);
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE4');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE4
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E4NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: وجود ایندکس تضمین استفاده از آن نیست؛ Optimizer بر پایه آمار، تعداد ردیف و هزینه تخمینی تصمیم می‌گیرد. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

مثال 5: تنظیم گزینه‌های ساخت و نگهداری با CREATE NONCLUSTERED COLUMNSTORE INDEX

یکی از گزینه‌های متداول ساخت ایندکس مانند FILLFACTOR، SORT_IN_TEMPDB یا فشرده‌سازی در یک سناریوی کنترل‌شده نمایش داده می‌شود. در این مثال، هدف عملی افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است.

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE5', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE5;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE5
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE5
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E5
        ON dbo.DemoNonclusteredColumnstoreE5(SaleDate, ProductID, Quantity, NetAmount, RegionID);
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE5');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE5
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E5NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: هر گزینه هزینه و پیش‌نیاز خود را دارد؛ مقدار مناسب باید با نسخه SQL Server، Edition و الگوی بار واقعی آزموده شود. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

مثال 6: رفتار با NULL و داده‌های اختیاری با CREATE NONCLUSTERED COLUMNSTORE INDEX

داده‌ای دارای مقدار NULL وارد می‌شود تا اثر آن بر تعریف، انتخاب‌پذیری و نتیجه Query روشن شود. در این مثال، هدف عملی افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است.

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE6', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE6;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE6
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE6
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E6
        ON dbo.DemoNonclusteredColumnstoreE6(CustomerID, SaleDate, NetAmount, RegionID) WHERE RegionID IS NOT NULL;
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE6');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE6
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E6NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: NULL مقدار عادی نیست و قواعد یکتایی، فیلتر و برآورد Cardinality را باید آگاهانه بررسی کرد. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

مثال 7: سناریوی مرزی با دامنه تاریخی با CREATE NONCLUSTERED COLUMNSTORE INDEX

یک بازه تاریخی و حجم منطقی داده برای نشان‌دادن اثر ترتیب کلید، فیلتر یا Segment Elimination به کار می‌رود. در این مثال، هدف عملی افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است.

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE7', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE7;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE7
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE7
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E7
        ON dbo.DemoNonclusteredColumnstoreE7(CustomerID, ProductID, SaleDate, Quantity, NetAmount);
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE7');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE7
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E7NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: در بازه‌های بسیار بزرگ، به‌روز بودن Statistics و هماهنگی نوع پارامتر با نوع ستون اهمیت ویژه دارد. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

مثال 8: گزارش سازمانی و ستون‌های خروجی با CREATE NONCLUSTERED COLUMNSTORE INDEX

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

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE8', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE8;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE8
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE8
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E8
        ON dbo.DemoNonclusteredColumnstoreE8(SaleDate, ProductID, Quantity, NetAmount, RegionID);
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE8');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE8
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E8NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: هدف کاهش خواندن صفحه و حذف عملیات اضافه است، نه افزودن همه ستون‌های جدول به هر ایندکس. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

مثال 9: روش اشتباه و نسخه اصلاح‌شده با CREATE NONCLUSTERED COLUMNSTORE INDEX

یک خطای طراحی رایج ابتدا در Comment توضیح داده می‌شود و سپس تعریف اصلاح‌شده و قابل اجرا قرار می‌گیرد. در این مثال، هدف عملی افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است.

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE9', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE9;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE9
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE9
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E9
        ON dbo.DemoNonclusteredColumnstoreE9(CustomerID, SaleDate, NetAmount, RegionID);
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE9');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE9
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E9NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: بازبینی نام، نوع داده، ترتیب ستون و قابلیت‌های مجاز پیش از اجرای DDL از خطا و Downtime جلوگیری می‌کند. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

مثال 10: کنترل نتیجه و سنجش کارایی با CREATE NONCLUSTERED COLUMNSTORE INDEX

پس از ساخت، نمای سیستمی و یک Query نمونه برای کنترل نوع ایندکس و آماده‌سازی ارزیابی کارایی استفاده می‌شوند. در این مثال، هدف عملی افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ است.

IF OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE10', N'U') IS NOT NULL
        DROP TABLE dbo.DemoNonclusteredColumnstoreE10;
    
    CREATE TABLE dbo.DemoNonclusteredColumnstoreE10
    (
        SaleID      bigint IDENTITY(1,1) NOT NULL,
        CustomerID int NOT NULL,
        ProductID  int NOT NULL,
        SaleDate   date NOT NULL,
        Quantity   int NOT NULL,
        NetAmount  decimal(14,2) NOT NULL,
        RegionID   smallint NULL
    );
    
    INSERT INTO dbo.DemoNonclusteredColumnstoreE10
        (CustomerID, ProductID, SaleDate, Quantity, NetAmount, RegionID)
    VALUES
        (101, 10, '2026-07-01', 2, 150000.00, 1),
        (102, 11, '2026-07-10', 1,  87000.00, 2),
        (103, 10, '2026-07-20', 5, 390000.00, NULL);
    
    CREATE NONCLUSTERED COLUMNSTORE INDEX IX_DemoNonclusteredColumnstore_E10
        ON dbo.DemoNonclusteredColumnstoreE10(CustomerID, ProductID, SaleDate, Quantity, NetAmount);
    
    SELECT name, type_desc, is_disabled
    FROM sys.indexes
    WHERE object_id = OBJECT_ID(N'dbo.DemoNonclusteredColumnstoreE10');
    
    SELECT ProductID, SUM(NetAmount) AS TotalAmount
    FROM dbo.DemoNonclusteredColumnstoreE10
    GROUP BY ProductID;
    
نام یا شاخص کنترلنوع مورد انتظارنتیجه نمونه
IX_DemoNonclusteredColumnstore_E10NONCLUSTERED COLUMNSTOREتعریف در نمای سیستمی قابل مشاهده است و Query کنترل بدون خطای ساختاری اجرا می‌شود.

نکته کاربردی: نتیجه نهایی باید با Actual Execution Plan، STATISTICS IO و زمان اجرا در محیط آزمایشی مقایسه شود. برای ساخت ایندکس ستونی غیرخوشه‌ای همچنین باید انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را در بازبینی نهایی ثبت کرد.

خطاهای رایج و روش عیب‌یابی

خطای Duplicate Name زمانی رخ می‌دهد که نام ایندکس روی همان جدول از قبل وجود داشته باشد. پیش از Deployment با sys.indexes وضعیت را بررسی کنید و تصمیم بگیرید عملیات باید Create، Rebuild یا جایگزینی با DROP_EXISTING باشد. حذف خودکار ایندکس بدون شناخت وابستگی‌ها خطرناک است.

خطاهای مربوط به ستون، نوع داده یا طول کلید معمولاً از تفاوت Schema محیط‌ها ناشی می‌شوند. اسکریپت باید در پایگاه مقصد و با نام Schema صریح اجرا شود. برای داده‌های XML، Spatial، Full-Text و Columnstore پیش‌نیازهای اختصاصی را جداگانه کنترل کنید.

اگر دستور موفق بود اما Query سریع نشد، مسئله الزاماً از Create نیست. تبدیل ضمنی، عبارت غیرSARGable، Statistics قدیمی، پارامتر نامناسب یا Key Lookup پرهزینه می‌تواند باعث کنار گذاشته‌شدن ایندکس شود. Actual Plan پاسخ دقیق‌تری از حدس ارائه می‌دهد.

در این موضوع، انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها مهم‌ترین کنترل اختصاصی است. خطای عملیاتی فقط پیام SQL Server نیست؛ رشد Log، Blocking طولانی یا افزایش هزینه DML نیز یک شکست استقرار محسوب می‌شود.

ملاحظات کارایی و پایش

قبل و بعد از تغییر، SET STATISTICS IO و SET STATISTICS TIME را برای Query ثابت اجرا کنید. Logical Reads معیار مناسبی برای کاهش کار موتور است، اما باید CPU، Elapsed Time، Memory Grant و Waitها نیز کنار آن دیده شوند. یک نتیجه سریع در Cache گرم ممکن است تصویر ناقصی بدهد.

نمای sys.dm_db_index_usage_stats تعداد Seek، Scan، Lookup و Update را نشان می‌دهد، ولی پس از Restart ریست می‌شود. داده پایش را دوره‌ای ذخیره کنید تا ایندکس کم‌مصرف با ایندکس تازه‌ساخته اشتباه نشود. Query Store نیز تغییر Plan و Regression را قابل پیگیری می‌کند.

هر ایندکس جدید هزینه نوشتن دارد. اگر جدول تراکنشی پرتغییر است، تعداد و عرض کلیدها را محدود کنید. برای گزارش‌های حجیم، ساختار Columnstore یا گزارش جداگانه ممکن است از چند ایندکس Rowstore عریض مناسب‌تر باشد.

Fragmentation تنها معیار نگهداری نیست. روی ساختارهای کوچک اثر آن ناچیز است و در Columnstore باید کیفیت Rowgroup و تعداد ردیف‌های Deleted نیز دیده شود. برنامه نگهداری باید با نوع ساخت ایندکس ستونی غیرخوشه‌ای سازگار باشد.

بهترین روش‌ها

  1. نیاز را با Query واقعی و Plan معتبر اثبات کنید.
  2. تعریف‌های موجود را برای هم‌پوشانی و امکان ادغام بررسی کنید.
  3. کلید را تا حد ممکن باریک و هدفمند نگه دارید.
  4. گزینه‌های نسخه و Edition مقصد را پیش از استقرار کنترل کنید.
  5. ساخت را در محیط آزمایشی با حجم نزدیک به تولید زمان‌گیری کنید.
  6. اثر روی DML، Log، Backup و Replication را بسنجید.
  7. پس از استقرار Plan و شاخص‌های عملکرد را دوباره اندازه بگیرید.
  8. مالک، دلیل ایجاد و تاریخ بازبینی ایندکس را مستند کنید.
  9. برای ساخت ایندکس ستونی غیرخوشه‌ای، انتخاب ستون‌های تحلیلی، کنترل فضای کپی ستونی و اثر نگهداری بر تراکنش‌ها را به چک‌لیست اضافه کنید.
  10. در صورت نبود منفعت پایدار، با برنامه کنترل‌شده تغییر را بازگردانید.

سؤالات متداول

سؤال 1: CREATE NONCLUSTERED COLUMNSTORE INDEX دقیقاً چه کاری انجام می‌دهد؟

CREATE NONCLUSTERED COLUMNSTORE INDEX ساختاری ایجاد می‌کند که برای افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ طراحی شده است. موتور SQL Server با توجه به Predicate، آمار و هزینه تخمینی تصمیم می‌گیرد از آن استفاده کند؛ بنابراین ایجاد ساختار به‌تنهایی تضمین‌کننده سریع‌ترشدن همه Queryها نیست.

سؤال 2: چه زمانی ساخت ایندکس ستونی غیرخوشه‌ای انتخاب مناسبی است؟

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

سؤال 3: آیا افزودن این ایندکس هزینه پروژه را کاهش می‌دهد؟

اگر گلوگاه درست تشخیص داده شده باشد، کاهش زمان پاسخ، مصرف CPU و تعداد خواندن می‌تواند هزینه زیرساخت و پشتیبانی را کم کند. در پروژه حرفه‌ای باید هزینه ساخت، فضای دیسک، Log و نگهداری DML نیز در محاسبه بازگشت سرمایه وارد شود.

سؤال 4: برای سفارش طراحی ساخت ایندکس ستونی غیرخوشه‌ای چه اطلاعاتی لازم است؟

طرح جدول، Queryهای واقعی، Actual Execution Plan، حجم و رشد داده، نسخه SQL Server، پنجره نگهداری و شاخص‌های SLA اطلاعات پایه هستند. بدون این داده‌ها پیشنهاد ایندکس بیشتر شبیه حدس است تا یک تصمیم مهندسی قابل اندازه‌گیری.

سؤال 5: تفاوت این روش با یک ایندکس عمومی چیست؟

تفاوت اصلی در هدف ذخیره‌سازی و مسیر دسترسی است. CREATE NONCLUSTERED COLUMNSTORE INDEX بر افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ تمرکز دارد، در حالی که یک تعریف عمومی ممکن است فقط یک ستون را بدون توجه به پوشش Query، توزیع داده و هزینه تغییرات ایندکس کند.

سؤال 6: آیا می‌توان پیاده‌سازی را بدون توقف سرویس انجام داد؟

این موضوع به نوع ایندکس، نسخه و Edition، اندازه جدول، گزینه ONLINE و الگوی تراکنش بستگی دارد. حتی عملیات Online نیز می‌تواند قفل‌های کوتاه یا مصرف منابع قابل توجه داشته باشد؛ بنابراین زمان‌بندی، پایش و برنامه بازگشت ضروری است.

سؤال 7: رایج‌ترین خطا هنگام اجرای CREATE NONCLUSTERED COLUMNSTORE INDEX چیست؟

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

سؤال 8: اثر ساخت ایندکس ستونی غیرخوشه‌ای بر Performance چگونه سنجیده می‌شود؟

مقایسه باید با Query و پارامتر یکسان، Cache کنترل‌شده، Actual Execution Plan، SET STATISTICS IO و SET STATISTICS TIME انجام شود. فقط زمان یک اجرای منفرد معیار کافی نیست؛ خواندن منطقی، Memory Grant، Spill و اثر هم‌زمانی را هم ثبت کنید.

سؤال 9: بهترین روش نگهداری این ایندکس چیست؟

بر اساس نرخ تغییر، Fragmentation یا کیفیت Rowgroup، آمار مصرف و فضای ذخیره‌سازی برنامه نگهداری بسازید. بازسازی زمان‌بندی‌شده و کورکورانه مناسب نیست؛ تصمیم نگهداری باید مبتنی بر اندازه، Page Count، نوع ساختار و اثر واقعی بر Query باشد.

سؤال 10: این دستور با کدام نسخه‌های SQL Server سازگار است؟

هسته دستور در نسخه‌های پشتیبان آن قابل استفاده است، اما گزینه‌ها و قابلیت‌های تکمیلی میان نسخه‌ها، Editionها و سرویس‌های ابری تفاوت دارند. پیش از استفاده از ONLINE، فشرده‌سازی، Columnstore پیشرفته یا گزینه‌های خاص، مستندات همان نسخه سرور را کنترل کنید.

سؤالات مصاحبه تخصصی

پرسش مصاحبه 1: چگونه ثابت می‌کنید ساخت ایندکس ستونی غیرخوشه‌ای لازم است؟

با استخراج Queryهای پرهزینه از Query Store یا مانیتورینگ، بررسی Plan، سنجش Selectivity و مقایسه IO قبل و بعد. پاسخ حرفه‌ای باید هزینه نوشتن و نگهداری را نیز کنار منفعت خواندن قرار دهد.

پرسش مصاحبه 2: ترتیب ستون‌ها را چگونه انتخاب می‌کنید؟

ستون‌های Equality، Range، Join و Sort را بر اساس الگوی Query و توزیع داده تحلیل می‌کنم. قانون ثابت جایگزین آزمایش نیست و کلید نهایی باید با چند Query مهم و پارامترهای واقعی اعتبارسنجی شود.

پرسش مصاحبه 3: اگر Optimizer از ایندکس استفاده نکرد چه می‌کنید؟

آمار، SARGability، تبدیل ضمنی، Parameter Sniffing، تخمین Cardinality و هزینه Lookup را بررسی می‌کنم. اجبار Hint آخرین انتخاب است، زیرا ممکن است با تغییر داده یا نسخه به تصمیم نامناسب تبدیل شود.

پرسش مصاحبه 4: چه شاخص‌هایی بعد از استقرار پایش می‌شوند؟

زمان پاسخ، Logical Read، CPU، تعداد Scan و Seek، نرخ Update، فضای ایندکس، انتظارهای قفل و تغییر Plan پایش می‌شوند. هدف اثبات پایداری منفعت در بار واقعی است.

پرسش مصاحبه 5: برنامه بازگشت برای این تغییر چیست؟

اسکریپت حذف یا بازگردانی تعریف قبلی، نسخه پشتیبان DDL، معیار توقف، زمان مجاز و مسئول تصمیم مشخص می‌شوند. برای جدول بزرگ، ظرفیت Log و فضای TempDB نیز قبل از عملیات برآورد می‌شود.

چک‌لیست نهایی

  • نام پایگاه، Schema، جدول و ستون‌ها تأیید شده‌اند.
  • نسخه پشتیبان تعریف قبلی و برنامه Rollback آماده است.
  • فضای Data File، Log و TempDB بررسی شده است.
  • Query و Plan مبنا پیش از تغییر ذخیره شده‌اند.
  • مثال استقرار در محیط آزمایشی بدون خطا اجرا شده است.
  • قفل، زمان اجرا و اثر روی کاربران پایش می‌شود.
  • آمار IO و زمان پس از ساخت دوباره ثبت می‌شوند.
  • مستندات و تاریخ بازبینی بعدی ثبت شده‌اند.

جمع‌بندی

CREATE NONCLUSTERED COLUMNSTORE INDEX زمانی ارزشمند است که تعریف آن از نیاز واقعی استخراج و اثرش با اندازه‌گیری اثبات شود. این دستور برای افزودن نمای ستونی تحلیلی روی جدول Rowstore و ترکیب OLTP با گزارش‌گیری نزدیک به بلادرنگ به کار می‌رود، اما هزینه نوشتن، فضا و نگهداری باید همراه با منفعت خواندن سنجیده شود.

ده مثال این مقاله الگوهای پایه تا کنترل عملیاتی را نشان دادند. برای محیط تولید، نام‌ها و ستون‌ها را با Schema خود تطبیق دهید، اسکریپت را در Staging اجرا کنید و پس از استقرار نیز Plan و شاخص‌های کارایی را پایش کنید.

برای مقایسه این روش با سایر ساختارها به مقاله مادر آموزش انواع دستور CREATE INDEX بازگردید.

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

حرف 500 حداکثر