Để lấy dữ liệu theo từng trang/lô (batch) thay vì tải toàn bộ, MySQL cung cấp LIMIT (số hàng tối đa) và OFFSET (bỏ qua bao nhiêu hàng đầu).
Cú pháp
SELECT * FROM ten_bang ORDER BY cot_sap_xep LIMIT so_hang_moi_lot OFFSET so_hang_bo_qua;
Hoặc viết gọn: LIMIT offset, count (thứ tự ngược: offset trước, count sau).
Ví dụ minh họa
Tạo bảng 10 hàng:
mysql> CREATE TABLE DemoTable1514 (
-> Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> FirstName VARCHAR(20)
-> );
mysql> INSERT INTO DemoTable1514(FirstName) VALUES
-> ('Chris'),('Bob'),('Sam'),('Mike'),('Carol'),
-> ('David'),('Robert'),('Adam'),('John'),('Jace');
Lấy lô 2 (hàng 5-8), mỗi lô 4 hàng:
mysql> SELECT * FROM DemoTable1514 LIMIT 4 OFFSET 4;
Kết quả (bỏ 4 hàng đầu, lấy 4 hàng tiếp):
+----+-----------+ | Id | FirstName | +----+-----------+ | 5 | Carol | | 6 | David | | 7 | Robert | | 8 | Adam | +----+-----------+
Công thức phân trang
- Trang
page(bắt đầu từ 1), kích thướcpageSize: OFFSET = (page - 1) * pageSizeLIMIT = pageSize
⚠️ Vấn đề hiệu năng OFFSET lớn
Khi OFFSET lớn (trang sau), MySQL vẫn phải **đọc và bỏ qua** các hàng trước → chậm dần.
Giải pháp Keyset Pagination (Cursor-based):
-- Trang đầu SELECT * FROM bang ORDER BY id LIMIT 20; -- Trang sau (dùng ID cuối trang trước) SELECT * FROM bang WHERE id > 20 ORDER BY id LIMIT 20;
- Yêu cầu cột sắp xếp **duy nhất** (unique) và có index.
- Không hỗ trợ nhảy trang tùy ý (chỉ next/prev).
- Hiệu năng không đổi theo số trang.
Lưu ý
- Luôn có
ORDER BYxác định để kết quả ổn định. LIMIT 0trả về 0 hàng (hữu ích kiểm tra cấu trúc).- MySQL 8.0.18+ hỗ trợ
OFFSET ... ROWS FETCH NEXT ... ROWS ONLY(chuẩn SQL).