Clustered، Nonclustered، Filtered و Columnstore Indexها | Pro SQL Server 2019 Administration

Clustered، Nonclustered، Filtered و Columnstore Indexها

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

نظرات 0

Clustered، Nonclustered، Filtered و Columnstore Indexها

Chapter 8 — Clustered and Nonclustered Indexes

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

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

محدوده: صفحات PDF 262 تا 280

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

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

PAGE-262

فصل ۸ — Indexes and Statistics

SQL Server انواع مختلف Index را برای بهبود دسترسی به داده فراهم می‌کند و Statistics را برای برآورد Cardinality و انتخاب Plan نگه می‌دارد. این بخش با Clustered و Nonclustered Index شروع می‌شود و سپس به Covering، Filtered و Columnstore می‌رسد.

PAGE-263

Heap و Clustered Index

جدولی که Clustered Index ندارد Heap است. رکوردهای Heap روی Pageها قرار می‌گیرند و Row Identifier برای یافتن رکورد لازم است. Heap در برخی الگوها مناسب است، اما جست‌وجوی ترتیبی یا Range اغلب به Scan بیشتری نیاز دارد. Clustered Index داده را در Leaf Level بر اساس کلید مرتب می‌کند.

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

Clustered Index ساختار B-tree دارد: Root و Intermediate Level حاوی کلیدها و Pointerها هستند و Leaf Level خودِ Data Pageهاست. برای یافتن یک مقدار، موتور از Root به Leaf حرکت می‌کند. در Range Scan، پس از رسیدن به نقطه شروع، Pageهای Leaf به ترتیب پیمایش می‌شوند.

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

برای Range Query ممکن است Optimizer ترکیبی از Seek تا اولین مقدار و سپس Scan ترتیبی Leaf Level را انتخاب کند. کیفیت کلید Clustered اهمیت زیادی دارد: کلید Narrow، Stable، Unique و ترجیحاً Ever-Increasing باعث کاهش سربار Nonclustered Indexها و Page Split می‌شود.

PAGE-266

NEWSEQUENTIALID() می‌تواند برای GUIDهای ترتیبی‌تر مفید باشد، اما پس از Restart ممکن است توالی نسبت به مقادیر پیشین تغییر کند. همچنین کلید Clustered در Leafهای Nonclustered Index نگهداری می‌شود؛ بنابراین کلید پهن، همه NCIها را بزرگ‌تر می‌کند.

PAGE-267

ساخت Clustered Index

CREATE DATABASE Chapter8;
GO
USE Chapter8;
GO
CREATE TABLE dbo.CIDemo
(
  ID int IDENTITY,
  DummyText varchar(30)
);
CREATE UNIQUE CLUSTERED INDEX CI_CIDemo ON dbo.CIDemo(ID);

فایل‌های Database در محیط خود باید با مسیرهای صحیح تنظیم شوند. Index می‌تواند همزمان با CREATE TABLE/Constraint یا با CREATE INDEX ساخته شود.

Table 8-1 — بازنمایی متن فنی جدول منبع
--- PDF PAGE 267 ---
250
Listing 8-1.  Creating a Clustered Index
--Create Chapter8 Database
CREATE DATABASE Chapter8
 ON  PRIMARY
( NAME = N'Chapter8', FILENAME =
    N'F:\Program Files\Microsoft SQL Server\MSSQL15.PROSQLADMIN\MSSQL\DATAChapter8.mdf'),
 FILEGROUP [MEM] CONTAINS MEMORY_OPTIMIZED_DATA  DEFAULT
( NAME = N'MEM', FILENAME = N'H:\DATA\CH08')
 LOG ON
( NAME = N'Chapter8_log', FILENAME =
    N'E:\Program Files\Microsoft SQL Server\MSSQL15.PROSQLADMIN\MSSQL\DATAChapter8_log.ldf') ;
GO
USE Chapter8
GO
--Create CIDemo table
CREATE TABLE dbo.CIDemo
(
    ID       INT       IDENTITY,
    DummyText     VARCHAR(30)
) ;
GO
--Create clustered index
CREATE UNIQUE CLUSTERED INDEX CI_CIDemo ON dbo.CIDemo([ID]) ;
GO
When creating an index, you have a number of WITH options that you can specify. 
These options are outlined in Table 8-1.
Chapter 8  Indexes and Statistics

--- PDF PAGE 268 ---
251
Table 8-1.  Clustered Index WITH Options
Option
Description
MAXDOP
Specifies how many cores are used to build the index. Each core that is 
used builds its own portion of the index. The trade-off is that a higher 
MAXOP builds the index faster, but a lower MAXDOP means the index is 
built with less fragmentation.
FILLFACTOR
Specifies how much free space should be left in each page of the leaf 
level of the index. This can help reduce fragmentation caused by inserts 
at the expense of having a wider index, which requires more IO to read. 
For a clustered index, with a nonchanging, ever-increasing key, always 
set this to 0, which means 100% full minus enough space for one row.
PAD_INDEX
Applies the fill factor percentage to the intermediate levels of the B-tree.
STATISTICS_
NORECOMPUTE
Turns on or off the automatic updating of distribution statistics. Statistics 
are discussed later in this chapter.
SORT_IN_TEMPDB
Specifies that the intermediate sort results of the index should be stored 
in TempDB. When you use this option, you can offload IO to the spindles 
hosting TempDB, but this is at the expense of using more disk space. 
Cannot be ON if RESUMABLE is ON.
STATISTICS_
INCREMENTAL
Specifies if statistics should be created per partition. Limitations to this 
are discussed later in this chapter.
DROP_EXISTING
Used to drop and rebuild the existing index with the same name.
IGNORE_DUP_KEY
When you enable this option, an INSERT statement that tries to insert a 
duplicate key value into a unique index will not fail. Instead, a warning is 
generated and only the rows that break the unique constraint fail.
ONLINE
Can be set as ON or OFF, with a default of OFF. Specifies if the entire 
table and indexes should be locked for the duration of the index build or 
rebuild. If ON, then queries are still able to access the table during the 
operation. This is at the expense of the time it takes to build the index. 
For clustered indexes, this option is not available if the table contains 
LOB data.*
(continued)
Chapter 8  Indexes and Statistics

--- PDF PAGE 269 ---
252
As mentioned earlier in this chapter, if you create a primary key on a table, then 
unless you specify the NONCLUSTERED keyword, or a clustered index already exists, a 
clustered index is created automatically to cover the column(s) of the primary key. Also, 
remember that at times you may wish to move the clustered index to a more suitable 
column if the primary key is wide or if it is not ever-increasing.
In order to achieve this, you need to drop the primary key constraint and then re-­
create it using the NONCLUSTERED keyword. This forces SQL Server to cover the primary 
key with a unique nonclustered index. Once this is complete, you are able to create the 
clustered index on the column of your choosing.
If you need to remove a clustered index that is not covering a primary key, you can 
do so by using the DROP INDEX statement, as demonstrated in Listing 8-2, which drops 
the clustered index that we created in the previous example.
Listing 8-2.  Dropping the Index
DROP INDEX CI_CIDemo ON dbo.CIDemo ;
Table 8-1.  (continued)
Option
Description
OPTIMIZE_FOR_
SEQUENTIAL_KEY
Optimizes high concurrency inserts, where the index key is sequential. 
Introduced in SQL Server 2019, this feature is designed for indexes that 
suffer from last-page insert contention.
RESUMABLE
Can be set as ON or OFF, with a default of OFF. Specifies if the index 
creation or build can be paused and resumed or can be resumed after a 
failure. Can only be set to ON if ONLINE is set to ON.
MAX_DURATION
Specifies, in minutes, the maximum duration that an index rebuild or 
rebuild will execute for, before pausing. Can only be specified if ONLINE 
is set to ON and RESUMABLE is set to ON.
ALLOW_ROW_LOCKS
Specifies that you can take row locks out when accessing the table. This 
does not mean that they definitely will be taken.
ALLOW_PAGE_LOCKS
Specifies that you can take page locks out when accessing the table. 
This does not mean that they definitely will be taken.
*Spatial data is regarded as LOB data.
Chapter 8  Indexes and Statistics
PAGE-268

گزینه‌های ساخت Index

گزینه‌های مهم Clustered Index
گزینهکاربرد
MAXDOPتعداد Processorهای مورد استفاده برای Build
FILLFACTORدرصد پرشدن Leaf Page و فضای آزاد برای رشد
SORT_IN_TEMPDBانجام عملیات Sort در TempDB
ONLINEکاهش Blocking هنگام Build/Rebuild در Edition/عملیات پشتیبانی‌شده
DATA_COMPRESSIONاعمال ROW/PAGE روی Index یا Partition
DROP_EXISTINGجایگزینی Index موجود با ساختار جدید
PAGE-269

Index را می‌توان با DROP INDEX حذف کرد. هنگام تغییر Clustered Index باید به هزینه بازسازی Nonclustered Indexها توجه کرد، زیرا Row Locator آن‌ها به کلید Clustered وابسته است. بعضی گزینه‌ها مثل ONLINE، MAXDOP و SORT_IN_TEMPDB روی مدت زمان و مصرف Resource اثر قابل توجه دارند.

PAGE-270

Nonclustered Index

Nonclustered Index یک B-tree جدا از Data است. Leaf Level آن Keyهای NCI و Row Locator را نگه می‌دارد. اگر جدول Clustered باشد Row Locator همان Clustered Key است؛ اگر Heap باشد RID استفاده می‌شود. NCI امکان Seek سریع روی ستون‌هایی را می‌دهد که ترتیب فیزیکی اصلی جدول بر اساس آن‌ها نیست.

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

Covering Index

وقتی تمام ستون‌های لازم Query در Key یا INCLUDE یک NCI موجود باشند، Query Covered است و برای گرفتن ستون اضافی به Lookup روی Clustered Index/Heap نیاز ندارد. INCLUDE اجازه می‌دهد ستون‌های خروجی در Leaf ذخیره شوند بدون آن‌که بخشی از Key و محدودیت اندازه کلید باشند.

PAGE-272

در NCI، ستون‌های Key برای جست‌وجو و مرتب‌سازی و ستون‌های INCLUDE برای پوشش خروجی مناسب‌اند. افزودن ستون بیش از حد، حجم Index و هزینه DML را افزایش می‌دهد. طراحی باید تعادل میان Read Performance، Storage و هزینه Insert/Update/Delete را حفظ کند.

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

ایجاد داده آزمایشی و Nonclustered Index

کتاب جداول CustomersDisk و OrdersDisk را با داده آزمایشی می‌سازد و سپس NCI روی Balance ایجاد می‌کند. داده‌ها با CTE و انتخاب تصادفی Name/Number تولید می‌شوند تا Queryهای مثال روی حجم قابل توجهی اجرا شوند.

PAGE-274

CustomersDisk شامل CustomerID، نام، Address ID، CreditLimit و Balance است. Primary Key روی CustomerID قرار می‌گیرد. سپس داده‌های تصادفی در جدول درج می‌شوند تا تأثیر NCI و Covering Index قابل مشاهده باشد.

PAGE-275

OrdersDisk شامل OrderNumber، OrderDate، CustomerID، ProductID، Quantity، NetAmount و DeliveryDate است. داده سفارش نیز از مجموعه اعداد و Customerهای ایجادشده تولید می‌شود. این جدول مبنای بسیاری از مثال‌های Index در ادامه فصل است.

PAGE-276

پس از درج داده، Tableهای موقت پاک و Foreign Key میان OrdersDisk.CustomerID و CustomersDisk.CustomerID اضافه می‌شود. سپس NCI اولیه روی Balance ساخته می‌شود.

PAGE-277

INCLUDE و Filtered Index

CREATE NONCLUSTERED INDEX NCI_Balance
ON dbo.CustomersDisk(Balance)
INCLUDE(LastName, FirstName)
WITH (DROP_EXISTING = ON);

Filtered Index فقط زیرمجموعه‌ای از Rowها را نگه می‌دارد و می‌تواند برای Queryهای انتخابی بسیار کوچک‌تر و ارزان‌تر باشد. Filter با WHERE تعریف می‌شود و محدودیت‌هایی دارد؛ Predicate باید ساده و قابل پشتیبانی باشد.

PAGE-278
CREATE NONCLUSTERED INDEX NonDeliveredItems
ON dbo.OrdersDisk(DeliveryDate)
WHERE DeliveryDate IS NULL;

Indexهای تخصصی و Columnstore

علاوه بر B-tree، SQL Server برای Memory-Optimized و Data Warehouse ساختارهای تخصصی دارد. Columnstore به جای ذخیره Row کامل روی Page، داده را ستونی سازمان‌دهی می‌کند و برای Queryهای تحلیلی روی جدول‌های بزرگ طراحی شده است.

PAGE-279

Columnstore رکوردها را در Rowgroupهای حدود 102,400 تا 1,048,576 سطری سازمان می‌دهد. هر Rowgroup به Column Segmentها تقسیم و با VertiPaq فشرده می‌شود. Metadata هر Segment به Elimination کمک می‌کند و Batch Mode امکان پردازش دسته‌ای حدود هزار Row را فراهم می‌کند؛ در نتیجه I/O، Memory و CPU برای workload تحلیلی کاهش می‌یابد.

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

Clustered Columnstore Index

در Clustered Columnstore کل جدول به‌صورت Columnstore ذخیره می‌شود. Insertهای کوچک ابتدا ممکن است وارد Deltastore Rowstore شوند و پس از رسیدن به حد مناسب، Tuple Mover آن‌ها را فشرده و به Rowgroup منتقل می‌کند. Query Engine Deltastore و Rowgroupهای فشرده را به‌صورت شفاف یک مجموعه واحد می‌بیند.

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

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

☆☆☆☆☆

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

 

0 نظر

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

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

0 / 500