Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Bỏ qua (skip) hàng trong MySQL với LIMIT OFFSET

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 BY xác định khi dùng LIMIT/OFFSET.
  • OFFSET 0 tươ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).