# SQL Server Index Fundamentals for .NET Developers

Giả sử bảng `Events` có 20 triệu rows:

“`sql
SELECT *
FROM Events
WHERE OrganizationId = @organizationId
AND EndTime >= @now;
“`

SQL Server sẽ tìm đúng rows như thế nào mà không phải scan toàn bộ bảng?

Đây là lúc index trở nên quan trọng.

## Clustered Index

Clustered index quyết định cách data rows được tổ chức theo key trong cấu trúc index chính.

Một table chỉ có một clustered index.

Ví dụ thường gặp:

“`sql
PRIMARY KEY CLUSTERED (Id)
“`

## Nonclustered Index

Là một index riêng trỏ tới row dữ liệu.

“`sql
CREATE INDEX IX_Events_OrganizationId
ON Events(OrganizationId);
“`

Một table có thể có nhiều nonclustered indexes.

## Composite Index

Index nhiều columns:

“`sql
CREATE INDEX IX_Events_Organization_EndTime
ON Events(OrganizationId, EndTime);
“`

Column order rất quan trọng.

Index:

“`text
(OrganizationId, EndTime)
“`

phù hợp với:

“`sql
WHERE OrganizationId = @orgId
AND EndTime >= @now
“`

nhưng không nhất thiết tối ưu cho:

“`sql
WHERE EndTime >= @now
“`

## Covering Index

Một index có thể chứa đủ columns để query không cần quay lại base table.

“`sql
CREATE INDEX IX_Events_Org_EndTime
ON Events(OrganizationId, EndTime)
INCLUDE (Name, Status, CreatedAt);
“`

Điều này có thể giảm Key Lookup.

## Seek vs Scan

### Index Seek

SQL Server tìm đúng range cần thiết.

### Index Scan

SQL Server đọc phần lớn hoặc toàn bộ index.

Scan không phải lúc nào cũng xấu. Nếu query cần phần lớn dữ liệu thì scan có thể hợp lý hơn.

## Index trade-offs

Index cải thiện read nhưng làm tăng write cost.

Mỗi:

“`text
INSERT
UPDATE
DELETE
“`

có thể phải cập nhật nhiều indexes.

Vì vậy không phải càng nhiều index càng tốt.

## How to think about index design

Với query:

“`sql
SELECT Id, Name, EndTime
FROM Events
WHERE OrganizationId = @orgId
AND EndTime >= @now
ORDER BY CreatedAt DESC;
“`

Hãy nghĩ theo:

“`text
Equality filter
+
Range filter
+
Sort
+
Returned columns
“`

## Interview question

### How do you choose an index?

> I start from the query pattern: equality predicates, range predicates, sort order, join columns, and returned columns. Then I validate the result with the actual execution plan and real workload rather than assuming the index is correct.

## Key takeaways

– Column order matters.
– Seek không tự động nghĩa là tốt.
– Index có write cost.
– Index design phải dựa trên workload thực tế.

**Next:** Part 5 — Understanding Execution Plans