Primary Key và thứ tự Insert
Vì index là sorted list, vị trí insert entry mới ảnh hưởng lớn đến performance ghi.
- Thêm vào cuối (giá trị luôn tăng): nhanh - vị trí cuối luôn được cache trong memory.
- Thêm vào giữa (giá trị random): chậm - phải tìm vị trí đúng, có thể di chuyển entries xung quanh, và page chứa vị trí đó có thể không nằm trong memory → trigger disk I/O.
So sánh các loại Primary Key
| Loại PK | Giá trị mẫu | Thứ tự insert | Tốc độ |
|---|---|---|---|
| Auto-increment | 1, 2, 3, 4… | Luôn tăng → cuối list | Nhanh nhất |
| UUIDv4 | a3f8b2c1-... (random) | Random → giữa list | Chậm nhất |
| UUIDv7 / ULID | 019abc12-... (time-based) | Gần như tăng → gần cuối | Nhanh |
| Snowflake ID | 142506829879... (time-based) | Luôn tăng → cuối list | Nhanh |
Mức độ ảnh hưởng: bảng MySQL 10 triệu row, insert với UUIDv4 chậm hơn 3-5 lần so với auto-increment. Càng lớn càng tệ vì index không fit memory → mỗi random insert có thể trigger disk I/O.
MySQL bị nặng hơn PostgreSQL
- MySQL (InnoDB): nghiêm trọng nhất vì dùng Clustered Index (PK = table) - cả bảng dữ liệu phải insert đúng vị trí sorted.
- PostgreSQL (Heap Table): nhẹ hơn vì dữ liệu bảng append vào cuối bất kể PK là gì - chỉ secondary index bị ảnh hưởng.
- Nhưng bảng hàng triệu row + insert liên tục → nên dùng sorted key cho cả hai.
Thực tiễn
Dùng auto-increment integer hoặc UUIDv7/ULID dạng binary (lưu BINARY(16) thay vì CHAR(36)) làm primary key. Chi tiết trade-off bảo mật/phân tán: xem UUID vs Auto-increment.
Liên quan
- B+ Tree - vì sao index là sorted list
- Index Write Overhead - chi phí ghi tổng thể khi có nhiều index