# Practical SQL Query Optimization for .NET Backend Engineers

Tối ưu query không nên bắt đầu bằng “thêm index”. Trước tiên cần xem query có được viết theo cách SQL Server dễ tối ưu hay không.

## SARGability

Không tốt:

“`sql
WHERE YEAR(CreatedAt) = 2026
“`

Tốt hơn:

“`sql
WHERE CreatedAt >= ‘2026-01-01’
AND CreatedAt < '2027-01-01' ``` Khi function được áp trực tiếp lên indexed column, SQL Server có thể khó sử dụng index hiệu quả. Một ví dụ khác: ```sql WHERE LOWER(Name) = 'abc' ``` cũng có thể gây vấn đề tương tự. ## LIKE với wildcard đầu ```sql WHERE Name LIKE '%abc%' ``` thường không tận dụng B-tree index tốt. ## Tránh SELECT * Không tốt: ```sql SELECT * FROM Events; ``` Tốt hơn: ```sql SELECT Id, Name, EndTime FROM Events; ``` Lợi ích: - ít IO - ít network - ít memory - dễ tạo covering index ## Offset Pagination ```sql ORDER BY CreatedAt DESC OFFSET 100000 ROWS FETCH NEXT 20 ROWS ONLY; ``` Offset lớn có thể ngày càng chậm. ## Keyset Pagination ```sql WHERE CreatedAt < @lastCreatedAt ORDER BY CreatedAt DESC FETCH NEXT 20 ROWS ONLY; ``` Thường scale tốt hơn vì database seek từ một boundary đã biết. ## N+1 Problem ```text SELECT Users ``` Sau đó: ```text for each user SELECT Orders ``` 100 users có thể tạo 101 queries. Giải pháp có thể là: - projection - join - controlled Include - batch query ## Interview questions ### What is a sargable predicate? > A sargable predicate allows the database engine to efficiently use an index to locate rows instead of applying a transformation to every row.

### Offset vs cursor pagination?

> Offset pagination is simple but becomes expensive at large offsets. Cursor or keyset pagination scales better because it seeks from a known key instead of skipping many rows.

## Key takeaways

Query optimization nên đi theo flow:

“`text
Query shape
↓
Indexes
↓
Execution plan
↓
Actual workload
“`

**Next:** Part 7 — EF Core Performance