فشردهسازی همه Rowgroupها با COMPRESS_ALL_ROW_GROUPS
فشردهسازی همه Rowgroupها با COMPRESS_ALL_ROW_GROUPS
گزینه COMPRESS_ALL_ROW_GROUPS = ON همراه REORGANIZE، علاوه بر Rowgroupهای بسته، Rowgroupهای باز Delta Store را نیز میبندد و برای انتقال سریعتر به Columnstore تلاش میکند. این گزینه باید پس از پایان بارگذاری و با درک اثر بر Insertهای بعدی استفاده شود. در این راهنما موضوع از سطح مقدماتی تا طراحی عملی، خطاهای رایج، ملاحظات کارایی و سناریوهای نگهداری بررسی میشود.
مخاطب مقاله برنامهنویسان، مدیران پایگاه داده و تحلیلگرانی هستند که میخواهند Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) را بدون تصمیمهای حدسی در Microsoft SQL Server بهکار بگیرند. بازگشت به راهنمای جامع کارایی Columnstore در SQL Server
تعریف و جایگاه موضوع
گزینه COMPRESS_ALL_ROW_GROUPS = ON همراه REORGANIZE، علاوه بر Rowgroupهای بسته، Rowgroupهای باز Delta Store را نیز میبندد و برای انتقال سریعتر به Columnstore تلاش میکند. این گزینه باید پس از پایان بارگذاری و با درک اثر بر Insertهای بعدی استفاده شود.
این قابلیت را باید در کنار مفاهیم COMPRESS_ALL_ROW_GROUPS، REORGANIZE، OPEN Rowgroup و CLOSED Rowgroup تحلیل کرد. تصمیم درست تنها با مشاهده یک Query سریع حاصل نمیشود؛ بلکه نرخ رشد داده، الگوی DML، نحوه بارگذاری، محدودیت منابع و زمان نگهداری نیز باید وارد مدل تصمیم شوند.
نکته نسخه: این گزینه مخصوص سناریوهای Columnstore و در مستندات برای فشردهسازی Rowgroupهای باز و بسته معرفی شده است؛ سازگاری دقیق نسخه بررسی شود.
چرا این موضوع مهم است؟
در جداول تحلیلی بزرگ، تفاوت میان طراحی درست و اجرای صرف یک دستور میتواند به اختلاف قابلتوجه در IO، CPU و زمان پاسخ منجر شود. COMPRESS_ALL_ROW_GROUPS وقتی ارزش واقعی ایجاد میکند که با هدف کسبوکار، الگوی Query و ظرفیت زیرساخت هماهنگ باشد.
- پایان Batch Load
- بستن OPEN Rowgroup
- آمادهسازی گزارش
- کاهش Delta Store
- Maintenance هدفمند
به همین دلیل لازم است معیار موفقیت پیش از پیادهسازی تعریف شود. برای نمونه میتوان زمان گزارش ماهانه، تعداد Rowgroupهای کمحجم، درصد ردیفهای حذفشده، حجم Log یا تعداد Segmentهای خواندهشده را بهعنوان شاخص پایه ثبت کرد.
این نمودار اجزای کلیدی «COMPRESS_ALL_ROW_GROUPS» و ارتباط میان COMPRESS_ALL_ROW_GROUPS، REORGANIZE و OPEN Rowgroup را نشان میدهد.
نحو، اجزا و پارامترهای اصلی
نحو پایه زیر نقطه شروع است. نام شیء، Schema، پارتیشن و گزینهها باید با محیط واقعی جایگزین شوند. در رشتههای فارسی SQL از پیشوند N استفاده شده تا داده یونیکد درست ذخیره شود.
ALTER INDEX CCI_FactSales ON dbo.FactSales REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
اجزای کلیدی
| مفهوم | نقش در موضوع | نکته عملی |
|---|
| COMPRESS_ALL_ROW_GROUPS | بخشی از معماری یا رفتار COMPRESS_ALL_ROW_GROUPS | فقط پس از پایان Load اجرا کنید |
| REORGANIZE | بخشی از معماری یا رفتار COMPRESS_ALL_ROW_GROUPS | Rowgroupهای بسیار کوچک را نسازید |
| OPEN Rowgroup | بخشی از معماری یا رفتار COMPRESS_ALL_ROW_GROUPS | پارتیشن تاریخی را جدا کنید |
| CLOSED Rowgroup | بخشی از معماری یا رفتار COMPRESS_ALL_ROW_GROUPS | قبل و بعد State را ثبت کنید |
| Delta Store | بخشی از معماری یا رفتار COMPRESS_ALL_ROW_GROUPS | گزینه را به شرط عملیاتی متصل کنید |
| Clustered Columnstore | بخشی از معماری یا رفتار COMPRESS_ALL_ROW_GROUPS | فقط پس از پایان Load اجرا کنید |
نوع خروجی بسته به موضوع ممکن است یک ساختار ایندکس، Plan اجرایی، مجموعه Rowgroup، شمارنده DMV یا مقدار عددی باشد. همیشه خروجی را با Metadata و Plan واقعی تأیید کنید؛ پیام موفقیت دستور بهتنهایی نشاندهنده بهبود نیست.
فرایند تصمیمگیری و پیادهسازی
- Workload اصلی را مشخص کنید و Queryهای پرتکرار مرتبط با COMPRESS_ALL_ROW_GROUPS را از Query Store یا مانیتورینگ استخراج کنید.
- وضعیت فعلی REORGANIZE و OPEN Rowgroup را ثبت کنید تا خط پایه قابل مقایسه باشد.
- Syntax را در محیط آزمایشی اجرا کنید و اثر آن را روی اندازه OPEN Rowgroup و زمان تا Batch بعدی بسنجید.
- سناریوهای بارگذاری، حذف، بهروزرسانی، گزارشگیری و بازیابی خطا را جداگانه آزمایش کنید.
- پس از تأیید، اجرای Production را با پنجره تغییر، Rollback Plan و گزارش کنترلی انجام دهید.
این روش مرحلهای مانع آن میشود که یک بهبود محلی، هزینه پنهان در ETL یا عملیات تراکنشی ایجاد کند. همچنین مستندسازی خروجیهای قبل و بعد، تصمیمهای نگهداری آینده را قابل دفاع میسازد.
در این جریان، داده از مرحله ورودی عبور میکند، در نقطههای کنترلی مرتبط با REORGANIZE و CLOSED Rowgroup ارزیابی میشود و سپس نتیجه قابل پایش تولید میگردد.
۱۰ مثال عملی از ساده تا حرفهای
مثال 1: اجرای پایه عملیات
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی اجرای پایه عملیات بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ اندازه OPEN Rowgroup را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
مثال 2: اجرای سطح پارتیشن
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی اجرای سطح پارتیشن بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE PARTITION = ALL WITH (COMPRESS_ALL_ROW_GROUPS = ON);
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ زمان تا Batch بعدی را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
مثال 3: سناریوی پس از تغییر داده
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی سناریوی پس از تغییر داده بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
INSERT INTO dbo.FactSalesDemo VALUES (30001,'2026-07-27',10,20,1,125.00);
ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ Log را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
مثال 4: کنترل وضعیت قبل از عملیات
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی کنترل وضعیت قبل از عملیات بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
SELECT state_desc,total_rows FROM sys.dm_db_column_store_row_group_physical_stats WHERE object_id=OBJECT_ID(N'dbo.FactSalesDemo');
ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ CPU را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
مثال 5: اندازهگیری زمان اجرا
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی اندازهگیری زمان اجرا بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
SET STATISTICS TIME ON;
ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
SET STATISTICS TIME OFF;
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ پارتیشن فعال را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
مثال 6: اجرای شرطی براساس DMV
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی اجرای شرطی براساس DMV بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
BEGIN TRANSACTION;
ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
COMMIT;
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ اندازه OPEN Rowgroup را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
مثال 7: مدیریت خطا در Job
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی مدیریت خطا در Job بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
IF EXISTS (SELECT 1 FROM sys.dm_db_column_store_row_group_physical_stats WHERE object_id=OBJECT_ID(N'dbo.FactSalesDemo') AND state_desc IN (N'OPEN',N'CLOSED')) ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ زمان تا Batch بعدی را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
مثال 8: اعتبارسنجی وضعیت پس از عملیات
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی اعتبارسنجی وضعیت پس از عملیات بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
SELECT state_desc,COUNT(*) FROM sys.dm_db_column_store_row_group_physical_stats WHERE object_id=OBJECT_ID(N'dbo.FactSalesDemo') GROUP BY state_desc;
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ Log را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
مثال 9: مقایسه شاخص قبل و بعد
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی مقایسه شاخص قبل و بعد بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
SELECT COUNT(*) AS open_groups FROM sys.dm_db_column_store_row_group_physical_stats WHERE object_id=OBJECT_ID(N'dbo.FactSalesDemo') AND state_desc=N'OPEN';
ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ CPU را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
مثال 10: گزارش نهایی مصرف و سلامت
در این مثال، «COMPRESS_ALL_ROW_GROUPS» در سناریوی گزارش نهایی مصرف و سلامت بررسی میشود. Query بهگونهای نوشته شده که در یک محیط آزمایشی SQL Server قابل اجرا باشد و نتیجه آن با DMV، خروجی تجمیعی یا Metadata کنترل شود.
USE tempdb;
DROP TABLE IF EXISTS dbo.FactSalesDemo;
CREATE TABLE dbo.FactSalesDemo
(
SaleID bigint NOT NULL,
OrderDate date NOT NULL,
CustomerID int NOT NULL,
ProductID int NOT NULL,
Quantity smallint NULL,
Amount decimal(18,2) NULL
);
INSERT INTO dbo.FactSalesDemo
(
SaleID, OrderDate, CustomerID, ProductID, Quantity, Amount
)
SELECT TOP (25000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
DATEADD(day, -ABS(CHECKSUM(NEWID())) % 730, CONVERT(date, '20260727')),
1 + ABS(CHECKSUM(NEWID())) % 5000,
1 + ABS(CHECKSUM(NEWID())) % 800,
1 + ABS(CHECKSUM(NEWID())) % 12,
CONVERT(decimal(18,2), 10 + ABS(CHECKSUM(NEWID())) % 50000 / 10.0)
FROM sys.all_objects AS a
CROSS JOIN sys.all_objects AS b;
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSalesDemo
ON dbo.FactSalesDemo;
ALTER INDEX CCI_FactSalesDemo ON dbo.FactSalesDemo REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
SELECT SUM(size_in_bytes) AS bytes_after FROM sys.dm_db_column_store_row_group_physical_stats WHERE object_id=OBJECT_ID(N'dbo.FactSalesDemo');
| شاخص | خروجی نمونه | تفسیر |
|---|
| قبل از عملیات | OPEN / CLOSED | وجود Delta Rowgroup یا حذف منطقی |
| بعد از عملیات | COMPRESSED | نتیجه مورد انتظار پس از اجرای موفق |
| نکته | وابسته به Workload | خروجی واقعی را با DMV کنترل کنید |
نکته فنی: هنگام استفاده از Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) فقط به موفقبودن دستور اکتفا نکنید؛ پارتیشن فعال را قبل و بعد اندازه بگیرید و اثر آن را روی Workload واقعی ثبت کنید.
خطاهای رایج
خطاهای زیر در پروژههای واقعی مرتبط با Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) دیده میشوند. شدت هر خطا به حجم داده و نسخه SQL Server وابسته است، اما اصل کنترل برای همه محیطها یکسان است.
- اجرای مداوم هنگام Insert
- استفاده روی نوع ایندکس نامناسب
- نادیده گرفتن Rowgroup کوچک حاصل
- اجرای کل جدول بهجای پارتیشن
- فرض بیهزینه بودن
مهمترین هشدار: اجرای مداوم هنگام Insert. پیش از هر تغییر گسترده، Backup/Restore آزمایشی، ظرفیت Log و امکان بازگشت را بررسی کنید.
ملاحظات کارایی و پایش
برای ارزیابی COMPRESS_ALL_ROW_GROUPS حداقل پنج محور باید همزمان دیده شود: اندازه OPEN Rowgroup, زمان تا Batch بعدی, Log, CPU, پارتیشن فعال. اندازهگیری تنها زمان اجرا ممکن است نتیجه گمراهکننده بدهد، زیرا Cache گرم، Parallelism، Memory Grant و بار همزمان روی نتیجه اثر دارند.
| معیار | چرا مهم است؟ | روش پیشنهادی |
|---|
| اندازه OPEN Rowgroup | اثر مستقیم بر کیفیت یا هزینه COMPRESS_ALL_ROW_GROUPS دارد | فقط پس از پایان Load اجرا کنید |
| زمان تا Batch بعدی | اثر مستقیم بر کیفیت یا هزینه COMPRESS_ALL_ROW_GROUPS دارد | Rowgroupهای بسیار کوچک را نسازید |
| Log | اثر مستقیم بر کیفیت یا هزینه COMPRESS_ALL_ROW_GROUPS دارد | پارتیشن تاریخی را جدا کنید |
| CPU | اثر مستقیم بر کیفیت یا هزینه COMPRESS_ALL_ROW_GROUPS دارد | قبل و بعد State را ثبت کنید |
| پارتیشن فعال | اثر مستقیم بر کیفیت یا هزینه COMPRESS_ALL_ROW_GROUPS دارد | گزینه را به شرط عملیاتی متصل کنید |
یک Snapshot منفرد برای تصمیم بلندمدت کافی نیست. داده پایش را در چند بازه کاری، پس از ETL و در ساعات اوج جمعآوری کنید تا روند واقعی مشخص شود.
این سناریو تفاوت میان اجرای بدون پایش و اجرای مبتنی بر Best Practice را برای COMPRESS_ALL_ROW_GROUPS مقایسه میکند؛ معیارهای اصلی شامل اندازه OPEN Rowgroup و زمان تا Batch بعدی هستند.
بهترین روشها
- فقط پس از پایان Load اجرا کنید
- Rowgroupهای بسیار کوچک را نسازید
- پارتیشن تاریخی را جدا کنید
- قبل و بعد State را ثبت کنید
- گزینه را به شرط عملیاتی متصل کنید
Best Practice بهمعنای اجرای یک نسخه ثابت برای همه سرورها نیست. باید توصیهها را با اندازه داده، Edition، Compatibility Level، معماری HA/DR و محدودیت پنجره نگهداری تطبیق داد.
پرسشهای متداول
COMPRESS_ALL_ROW_GROUPS دقیقاً چه مشکلی را حل میکند؟
گزینه COMPRESS_ALL_ROW_GROUPS = ON همراه REORGANIZE، علاوه بر Rowgroupهای بسته، Rowgroupهای باز Delta Store را نیز میبندد و برای انتقال سریعتر به Columnstore تلاش میکند. این گزینه باید پس از پایان بارگذاری و با درک اثر بر Insertهای بعدی استفاده شود. انتخاب آن باید براساس نوع بارکاری و معیارهای قابل اندازهگیری انجام شود.
برای شروع یادگیری Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) چه پیشنیازی لازم است؟
آشنایی با Execution Plan، ایندکسها و دستورات پایه T-SQL کافی است. سپس باید مفاهیم REORGANIZE و OPEN Rowgroup را روی یک پایگاه داده آزمایشی مشاهده کنید.
آیا COMPRESS_ALL_ROW_GROUPS برای همه پروژههای تجاری مناسب است؟
خیر. سودمندی آن به حجم داده، نسبت خواندن به نوشتن، SLA گزارشها و هزینه نگهداری وابسته است. ارزیابی فنی یا مشاوره SQL Server پیش از استقرار میتواند از هزینههای بازطراحی جلوگیری کند.
هزینه پیادهسازی COMPRESS_ALL_ROW_GROUPS چگونه برآورد میشود؟
برآورد باید شامل تحلیل Workload، طراحی آزمایش، زمان مهاجرت، پایش پس از اجرا و آموزش تیم باشد. اندازه جدول و حساسیت توقف سرویس نیز روی زمان انجام پروژه اثر مستقیم دارد.
تفاوت COMPRESS_ALL_ROW_GROUPS با یک ایندکس یا روش عمومی چیست؟
روش عمومی معمولاً فقط ساختار یا دستور را میبیند، اما این موضوع روی COMPRESS_ALL_ROW_GROUPS، CLOSED Rowgroup و رفتار واقعی موتور تمرکز دارد. مقایسه باید با Plan، IO، CPU و مدت اجرا انجام شود.
چه زمانی برای اجرای پروژه یا دریافت خدمات مرتبط با Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) مناسب است؟
هنگامی که گزارشها کند شدهاند، رشد داده سریع است یا نگهداری فعلی نتیجه قابل پیشبینی ندارد، بررسی تخصصی ارزشمند است. بهتر است ابتدا Snapshot فنی و معیار موفقیت تعیین شود.
رایجترین خطا در استفاده از COMPRESS_ALL_ROW_GROUPS چیست؟
یکی از خطاهای پرتکرار «اجرای مداوم هنگام Insert» است. خطای دیگر تصمیمگیری بدون مقایسه قبل و بعد و بدون توجه به نسخه SQL Server است.
COMPRESS_ALL_ROW_GROUPS چه اثری بر Performance دارد؟
اثر اصلی از مسیر اندازه OPEN Rowgroup، زمان تا Batch بعدی و Log دیده میشود. نتیجه میتواند بسیار مثبت یا در Workload نامناسب منفی باشد، بنابراین تست کنترلشده ضروری است.
بهترین روش عملی برای COMPRESS_ALL_ROW_GROUPS چیست؟
از یک محیط آزمایشی مشابه Production شروع کنید، فقط پس از پایان Load اجرا کنید و Rowgroupهای بسیار کوچک را نسازید را اجرا کنید و معیارها را در Query Store یا سامانه پایش ثبت نمایید.
سازگاری Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) با نسخههای SQL Server چگونه است؟
این گزینه مخصوص سناریوهای Columnstore و در مستندات برای فشردهسازی Rowgroupهای باز و بسته معرفی شده است؛ سازگاری دقیق نسخه بررسی شود. پیش از انتشار در Production، Syntax و گزینههای قابل پشتیبانی را روی همان Edition، Version و Compatibility Level بررسی کنید.
سؤالات مصاحبه
پاسخ مناسب به پرسشهای زیر باید علاوه بر تعریف، شامل سناریو، Trade-off، معیار اندازهگیری و نمونه T-SQL باشد.
- تفاوت COMPRESS_ALL_ROW_GROUPS و REORGANIZE را با یک سناریوی واقعی توضیح دهید.
- برای سنجش اثر Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) چه شاخصهایی را قبل و بعد ثبت میکنید؟
- در چه شرایطی «اجرای مداوم هنگام Insert» باعث افت کارایی میشود؟
- چگونه با استفاده از OPEN Rowgroup و CLOSED Rowgroup مشکل را عیبیابی میکنید؟
- در طراحی یک Job سازمانی برای COMPRESS_ALL_ROW_GROUPS چه کنترل خطا و Rollback در نظر میگیرید؟
- چرا توصیه «فقط پس از پایان Load اجرا کنید» برای محیط Production مهم است؟
چکلیست نهایی
- نسخه و Compatibility Level برای Maintenance: ALTER INDEX ... REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) کنترل شد.
- خط پایه IO، CPU، Duration و فضای مصرفی ثبت شد.
- Query و Syntax در محیط آزمایشی اجرا شد.
- اثرات DML و ETL جداگانه سنجیده شد.
- خروجی DMV یا Metadata پس از اجرا بررسی شد.
- Rollback Plan و ظرفیت Log مشخص شد.
- گزارش مقایسه قبل و بعد ذخیره شد.
- Job یا رویه نگهداری دارای شرط و کنترل خطا است.
جمعبندی
COMPRESS_ALL_ROW_GROUPS زمانی مفید است که از حالت یک دستور منفرد خارج و به یک فرایند اندازهگیریشده تبدیل شود. گزینه COMPRESS_ALL_ROW_GROUPS = ON همراه REORGANIZE، علاوه بر Rowgroupهای بسته، Rowgroupهای باز Delta Store را نیز میبندد و برای انتقال سریعتر به Columnstore تلاش میکند. این گزینه باید پس از پایان بارگذاری و با درک اثر بر Insertهای بعدی استفاده شود. در عمل باید با نسخه SQL Server، شکل داده و هدف گزارشگیری سازگار شود.
برای مطالعه ارتباط این موضوع با سایر اجزای Columnstore، راهنمای جامع کارایی Columnstore در SQL Server را ببینید.
خدمات برنامهنویسی و پایگاه داده
برنامهنویسی در اصفهان
قبول سفارشهای برنامهنویسی و پایگاه داده: 09131253620
انجام پروژههای برنامهنویسی، آموزش برنامهنویسی و آموزش پایگاه داده SQL Server با رویکرد حرفهای، مستندسازی مناسب و قابلیت توسعه انجام میشود.
مجموعهای معتبر با سابقه فعالیت حرفهای از سال ۱۳۷۵ شمسی
از سال ۱۳۷۵ شمسی تاکنون در زمینه طراحی و اجرای پروژههای برنامهنویسی، پایگاه داده، سیستمهای تحت وب، وبسایت و راهکارهای نرمافزاری فعالیت میکنیم.
برای سفارش پروژههای برنامهنویسی و پایگاه داده، سیستمهای تحت وب، وبسایت و راهکارهای نرمافزاری جدید، با شماره تلفن همراه 09131253620 تماس حاصل فرمایید.
ایتا، واتساپ و تماس مستقیم: +989131253620
تماس با ما