I. TỐI ƯU QUERY
1. Tạo Index đúng cách (Quan trọng nhất)
- Index cho cột trong WHERE
- Index cho cột trong JOIN
- Index cho cột trong ORDER BY
- Index cho cột trong GROUP BY
- Với composite index: cột lọc nhiều nhất đặt trước
2. Tránh SELECT *
- Chỉ select các cột cần dùng
- Giảm IO, memory và network traffic
3. Tránh dùng Function trong WHERE Sai: WHERE YEAR(CreatedDate) = 2026
Đúng: WHERE CreatedDate >= ‘2026-01-01’ AND CreatedDate <
‘2027-01-01’
4. Hạn chế OR
- Ưu tiên dùng IN
- Hoặc tách thành UNION ALL nếu cần
5. Dùng EXISTS thay vì IN khi subquery lớn
6. Pagination chuẩn
- SQL Server: OFFSET FETCH
- PostgreSQL: LIMIT OFFSET
- Bảng lớn nên dùng Keyset Pagination
7. Kiểm tra Execution Plan
- Tránh Table Scan
- Ưu tiên Index Seek
- Bật STATISTICS IO, TIME để đo hiệu năng
------------------------------------------------------------------------
II. TỐI ƯU STORED PROCEDURE
1. Tránh Parameter Sniffing (SQL Server)
- Dùng OPTION (RECOMPILE)
- Hoặc gán tham số sang biến local
2. Hạn chế Dynamic SQL
- Nếu cần dùng thì dùng sp_executesql
3. Tránh Transaction quá dài
- Chỉ wrap phần cần commit DB
- Không call API trong transaction
4. Giảm số lần round-trip DB
- Trả nhiều result set trong 1 Stored Procedure
5. Tránh dùng Cursor
- Ưu tiên Set-based query
- Dùng MERGE hoặc UPDATE FROM
------------------------------------------------------------------------
III. TỐI ƯU THIẾT KẾ DATABASE
1. Chuẩn hóa hợp lý
- Không over-normalize
- Hệ thống read-heavy có thể denormalize
2. Dùng đúng Data Type
- Không dùng NVARCHAR(MAX) nếu không cần
- Chọn size phù hợp để tiết kiệm bộ nhớ
3. Partition Table khi dữ liệu rất lớn
- Theo ngày / tháng / năm
------------------------------------------------------------------------
IV. CACHE & KIẾN TRÚC
1. Dùng Redis cache cho dữ liệu read-heavy
2. Áp dụng CQRS (tách Read & Write DB)
3. Dùng Background Job cho xử lý nặng
------------------------------------------------------------------------
CHECKLIST KHI QUERY CHẬM
- Có Table Scan không?
- Index có được dùng không?
- Có function trong WHERE không?
- Có implicit conversion không?
- Join có dư thừa không?
- Data type có mismatch không?
------------------------------------------------------------------------
ƯU TIÊN TRIỂN KHAI
1. Tạo index đúng
2. Kiểm tra execution plan
3. Bỏ SELECT *
4. Refactor query
5. Tối ưu Stored Procedure
6. Áp dụng cache nếu cần