Giới thiệu
Cú pháp LIMIT offset, row_count hoặc LIMIT row_count OFFSET offset cho phép bỏ qua offset hàng đầu và lấy row_count hàng tiếp theo. Dùng cho phân trang (pagination).
Ví dụ thực hành
1. Tạo bảng DemoTable860
mysql> CREATE TABLE DemoTable860 (
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(100)
);
2. Chèn 6 hàng
mysql> INSERT INTO DemoTable860(Name) VALUES ('Chris'),('Robert'),('David'),('Bob'),('Mike'),('Sam');
3. Bỏ 2 hàng đầu, lấy 3 hàng tiếp (trang 2, page size=3)
mysql> SELECT * FROM DemoTable860 LIMIT 3 OFFSET 2;
4. Kết quả
+----+-------+
| Id | Name |
+----+-------+
| 3 | David |
| 4 | Bob |
| 5 | Mike |
+----+-------+
Cú pháp tương đương
-- Cú pháp cũ (MySQL specific)
SELECT * FROM DemoTable860 LIMIT 2, 3; -- offset=2, count=3
-- Cú pháp chuẩn SQL:2008 (MySQL 8.0+ hỗ trợ)
SELECT * FROM DemoTable860 OFFSET 2 ROWS FETCH NEXT 3 ROWS ONLY;
⚠️ Vấn đề hiệu suất OFFSET lớn
Khi OFFSET 100000, MySQL vẫn phải đọc và bỏ qua 100.000 hàng → rất chậm.
Giải pháp: Keyset Pagination (Seek Method)
-- Trang đầu
SELECT * FROM DemoTable860 ORDER BY Id ASC LIMIT 3;
-- Trang tiếp theo: dùng Id cuối trang trước (last_id = 3)
SELECT * FROM DemoTable860 WHERE Id > 3 ORDER BY Id ASC LIMIT 3;
-- Trang trước: dùng Id đầu trang hiện tại (first_id = 4)
SELECT * FROM DemoTable860 WHERE Id < 4 ORDER BY Id DESC LIMIT 3;
- Tận dụng index trên
Id→ cực nhanh, không phụ thuộc offset. - Yêu cầu cột sắp xếp unique (PK hoặc unique index).
- Không hỗ trợ "nhảy đến trang N" trực tiếp (chỉ next/prev).
Lưu ý
- Luôn có
ORDER BYxác định khi dùng LIMIT/OFFSET. OFFSET 0tương đương không có OFFSET.- Kết hợp
SQL_CALC_FOUND_ROWS+FOUND_ROWS()để đếm tổng (deprecated MySQL 8.0.17+, dùng COUNT(*) riêng).