Columnstore و In-Memory Indexها و نگهداری Index | Pro SQL Server 2019 Administration

Columnstore و In-Memory Indexها و نگهداری Index

توسط admin | گروه SQL Server | 1405/05/20

نظرات 0

Columnstore و In-Memory Indexها و نگهداری Index

Chapter 8 — Columnstore, In-Memory Indexes and Index Maintenance

نویسنده: Peter A. Carter

زبان منبع: انگلیسی

محدوده: صفحات PDF 281 تا 299

تاریخ ترجمه: 2026-08-11

اعتبار ترجمه: ترجمه با کمک هوش مصنوعی

PAGE-281

در Clustered Columnstore، Insertهای بزرگ مستقیماً به Rowgroup فشرده تبدیل می‌شوند و Insertهای کوچک در Deltastore قرار می‌گیرند. Delete در Rowgroup معمولاً ابتدا Logical است و در Delete Bitmap ثبت می‌شود؛ Update نیز ترکیبی از حذف منطقی رکورد قبلی و درج نسخه جدید است. این ساختار اجازه می‌دهد Queryهای تحلیلی با فشرده‌سازی بالا اجرا شوند.

PAGE-282
SELECT * INTO dbo.OrdersColumnstore
FROM dbo.OrdersDisk;
GO
CREATE CLUSTERED COLUMNSTORE INDEX CCI_OrdersColumnstore
ON dbo.OrdersColumnstore;

برای Columnstore برخی انواع داده پشتیبانی نمی‌شوند. Nonclustered Columnstore روی Rowstore امکان ایجاد نسخه ستونی برای Queryهای تحلیلی را فراهم می‌کند؛ محدودیت‌های DML و قابلیت Update در نسخه‌های SQL Server باید با نسخه مورد استفاده تطبیق داده شود.

PAGE-283

Nonclustered Columnstore و In-Memory Hash Index

Nonclustered Columnstore می‌تواند مجموعه‌ای از ستون‌ها را برای تحلیل ستونی پوشش دهد. در Memory-Optimized Table دو خانواده اصلی Index وجود دارد: Hash و Nonclustered. Hash برای Equality Lookup با Key کامل بسیار سریع است و Bucket Count آن باید بر اساس Cardinality و رشد آینده انتخاب شود.

PAGE-284

Hash Index مقدار Hash کلید را به Bucket نگاشت می‌کند. Collision باعث می‌شود چند Entry در یک Bucket زنجیره شوند؛ Bucket Count خیلی کم زنجیره‌های طولانی و افت کارایی ایجاد می‌کند، در حالی که مقدار بسیار بزرگ حافظه بیشتری مصرف می‌کند. Unique بودن Index می‌تواند رفتار و طراحی را تغییر دهد.

PAGE-285

حافظه Hash Index پس از ساخت تا حد زیادی به تعداد Bucketها وابسته است، نه فقط تعداد Rowها. بنابراین Over-sizing می‌تواند Memory را هدر دهد. DMVهای XTP برای مشاهده Empty Bucket Percentage و Chain Length ابزار عملی ارزیابی طراحی Hash هستند.

Figure 8-7 — شکل/تصویر منبع، صفحه PDF 285
PAGE-286

ایجاد Memory-Optimized Hash Index

مثال فصل جدولی Memory-Optimized با Hash Index می‌سازد و داده Orders را در آن قرار می‌دهد. هدف مقایسه رفتار Hash و Nonclustered Index روی Predicateهای مختلف است. Equality روی کلید Hash سناریوی ایده‌آل است، در حالی که Range یا Predicate ناقص ممکن است Scan بیشتری ایجاد کند.

PAGE-287

برای جست‌وجوی Range یا ستون‌هایی که Hash مناسب آن‌ها نیست، Nonclustered Index روی Memory-Optimized Table اضافه می‌شود. SQL Server امکان ALTER/بازسازی طراحی Indexهای حافظه‌محور را با روش‌های مخصوص خود فراهم می‌کند.

PAGE-288

sys.dm_db_xtp_hash_index_stats

SELECT
  OBJECT_NAME(hs.object_id) AS TableName,
  i.name AS IndexName,
  hs.total_bucket_count,
  hs.empty_bucket_count,
  hs.avg_chain_length,
  hs.max_chain_length
FROM sys.dm_db_xtp_hash_index_stats AS hs
JOIN sys.indexes AS i
  ON hs.object_id = i.object_id AND hs.index_id = i.index_id;

نسبت Bucket خالی و طول Chain شاخص‌های اصلی تشخیص Bucket Count نامناسب‌اند.

PAGE-289

نگهداری Indexها

Indexها با گذر زمان تحت تأثیر DML، Page Split و تغییر توزیع داده قرار می‌گیرند. نگهداری باید مبتنی بر شواهد باشد: Missing Index Recommendation، Fragmentation، Statistics و هزینه واقعی Query. بازسازی بی‌قیدوشرط همه Indexها می‌تواند I/O، Log و Blocking زیادی ایجاد کند.

Figure 8-8 — شکل/تصویر منبع، صفحه PDF 289
PAGE-290

Missing Indexes

Optimizer هنگام Compile ممکن است تشخیص دهد Index مفیدی وجود ندارد و پیشنهاد Missing Index تولید کند. این پیشنهاد فقط از دید همان Query است؛ بنابراین نباید بدون بررسی workload کلی اجرا شود. ممکن است چند پیشنهاد هم‌پوشان را بتوان در یک Index بهتر ادغام کرد یا هزینه DML از منفعت Read بیشتر باشد.

Figure 8-9 — شکل/تصویر منبع، صفحه PDF 290
PAGE-291

DMVهای Missing Index اطلاعات Group، Equality/Inequality Columnها، Included Columnها و Usage را ارائه می‌کنند. داده‌های این DMV پس از Restart یا برخی رویدادها Reset می‌شوند؛ بنابراین برای تصمیم‌گیری بلندمدت باید Capture و تحلیل شوند.

PAGE-292

Index Fragmentation

Fragmentation منطقی زمانی رخ می‌دهد که ترتیب منطقی Pageها با ترتیب فیزیکی/زنجیره Leaf هماهنگ نباشد یا Page Density کاهش یابد. این مفهوم با Fragmentation فایل‌سیستم متفاوت است. اثر آن به Storage، Scan Pattern و اندازه Index وابسته است.

Figure 8-10 — شکل/تصویر منبع، صفحه PDF 292
PAGE-293

تشخیص Fragmentation

DMF ‏sys.dm_db_index_physical_stats با Modeهای LIMITED، SAMPLED و DETAILED وضعیت Pageها را گزارش می‌کند. پارامترهای Database ID، Object ID، Index ID و Partition Number اجازه می‌دهند دامنه بررسی محدود شود. DETAILED اطلاعات بیشتر ولی هزینه بالاتر دارد.

Table 8-2 — بازنمایی متن فنی جدول منبع
--- PDF PAGE 293 ---
276
page without page splits occurring. Many DBAs change the FILLFACTOR when they are 
not required to, however, which automatically causes internal fragmentation as soon as 
the index is built. PAD_INDEX can be applied only when FILLFACTOR is used, and it applies 
the same percentage of free space to the intermediate levels of the B-tree.
External fragmentation is also caused by page splits and refers to the logical order 
of pages, as ordered by the index key, being out of sequence when compared to the 
physical order of pages on disk. External fragmentation makes it so SQL Server is less 
able to perform scan operations using a sequential read, because the head needs to 
move backward and forward over the disk to locate the pages within the file.
Note  This is not the same as fragmentation at the file system level where a data 
file can be split over multiple, unordered disk sectors.
Detecting Fragmentation
You can identify fragmentation of indexes by using the sys.dm_db_index_physical_
stats DMF. This function accepts the parameters listed in Table 8-2.
Table 8-2.  sys.dm_db_index_physical_stats Parameters
Parameter
Description
Database_ID
The ID of the database that you want to run the function against. If you do 
not know it, you can pass in DB_ID('MyDatabase') where MyDatabase 
is the name of your database.
Object_ID
The Object ID of the table that you want to run the function against. If you 
do not know it, pass in OBJECT_ID('MyTable') where MyTable is the 
name of your table. Pass in NULL to run the function against all tables in 
the database.
Index_ID
The index ID of the index you want to run the function against. This is always 
1 for a clustered index. Pass in NULL to run the function against all indexes 
on the table.
(continued)
Chapter 8  Indexes and Statistics

--- PDF PAGE 294 ---
277
Listing 8-13 demonstrates how we can use sys.dm_db_index_physical_stats to 
check the fragmentation levels of our OrdersDisk table.
Listing 8-13.  sys.dm_db_index_physical_stats
USE Chapter8
GO
SELECT
i.name
,IPS.index_type_desc
,IPS.index_level
,IPS.avg_fragmentation_in_percent
,IPS.avg_page_space_used_in_percent
,i.fill_factor
,CASE
    WHEN i.fill_factor = 0
        THEN 100-IPS.avg_page_space_used_in_percent
    ELSE i.fill_factor-ips.avg_page_space_used_in_percent
END Internal_Frag_With_Fillfactor_Offset
,IPS.fragment_count
,IPS.avg_fragment_size_in_pages
Parameter
Description
Partition_Number
The ID of the partition that you want to run the function against. Pass in 
NULL if you want to run the function against all partitions or if the table is 
not partitioned.
Mode
Choose LIMITED, SAMPLED, or DETAILED. LIMITED only scans the non-
leaf levels of an index. SAMPLED scans 1% of pages in the table, unless the 
table has 10,000 pages or less, in which case DETAILED mode is used. 
DETAILED mode scans 100% of the pages in the table. For very large 
tables, SAMPLED is often preferred due to the length of time it can take to 
return data in DETAILED mode.
Table 8-2.  (continued)
Chapter 8  Indexes and Statistics
PAGE-294
SELECT *
FROM sys.dm_db_index_physical_stats
(
  DB_ID('Chapter8'),
  OBJECT_ID('dbo.OrdersDisk'),
  NULL, NULL, 'DETAILED'
);

در خروجی، avg_fragmentation_in_percent، page_count و avg_page_space_used_in_percent از شاخص‌های مفیدند. درصد Fragmentation بدون توجه به Page Count نباید مبنای خودکار تصمیم باشد.

PAGE-295

حذف Fragmentation

دو عملیات اصلی REORGANIZE و REBUILD هستند. REORGANIZE آنلاین‌تر و تدریجی است و Leaf Level را مرتب می‌کند؛ REBUILD ساختار Index را از نو می‌سازد، می‌تواند Statistics را نیز به‌روز کند و معمولاً Resource بیشتری مصرف می‌کند. آستانه ثابت برای همه سیستم‌ها وجود ندارد و باید با workload سازگار شود.

PAGE-296
CREATE NONCLUSTERED INDEX NCI_CustomerID
ON dbo.OrdersDisk(CustomerID);

ALTER INDEX NCI_CustomerID
ON dbo.OrdersDisk REORGANIZE;
PAGE-297
ALTER INDEX NCI_CustomerID
ON dbo.OrdersDisk
REBUILD WITH (MAXDOP = 1);

SSD مسئله Fragmentation منطقی را حذف نمی‌کند؛ فقط هزینه برخی I/Oها را تغییر می‌دهد. Rebuild می‌تواند با ONLINE و سایر Optionها تنظیم شود.

PAGE-298

Resumable Index Operations

ALTER INDEX NCI_CustomerID ON dbo.OrdersDisk
REBUILD WITH (ONLINE = ON, RESUMABLE = ON, MAXDOP = 1);

ALTER INDEX NCI_CustomerID ON dbo.OrdersDisk PAUSE;

Resumable Rebuild اجازه می‌دهد عملیات طولانی Pause و بعداً Resume شود و Window نگهداری بهتر مدیریت شود.

Figure 8-11 — شکل/تصویر منبع، صفحه PDF 298
PAGE-299
ALTER INDEX NCI_CustomerID ON dbo.OrdersDisk RESUME;
-- یا
ALTER INDEX NCI_CustomerID ON dbo.OrdersDisk ABORT;

ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_ONLINE = WHEN_SUPPORTED;
ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_RESUMABLE = WHEN_SUPPORTED;

Database Scoped Configuration می‌تواند رفتار پیش‌فرض Online/Resumable را در عملیات پشتیبانی‌شده ارتقا دهد.

امتیاز کاربران به این مقاله

☆☆☆☆☆

0 نفر امتیاز داده اند. میانگین: 0.0 از 5

 

0 نظر

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

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

0 / 500