Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

ดึงข้อมูล MySQL แบบแบ่งหน้า (Pagination) ด้วย LIMIT และ OFFSET

Pagination ใน MySQL: LIMIT + OFFSET

ใช้ LIMIT จำกัดจำนวนแถว และ OFFSET ข้ามแถวแรกๆ ไป เพื่อดึงข้อมูลทีละ "หน้า" (Batch)

ไวยากรณ์

SELECT * FROM table_name LIMIT page_size OFFSET offset_value;
-- หรือ
SELECT * FROM table_name LIMIT offset_value, page_size;

สร้างตารางและข้อมูล 10 แถว

mysql> CREATE TABLE DemoTable1514 (
    -> Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> FirstName VARCHAR(20)
    -> );
Query OK, 0 rows affected (0.63 sec)

mysql> INSERT INTO DemoTable1514(FirstName) VALUES
    -> ('Chris'), ('Bob'), ('Sam'), ('Mike'), ('Carol'),
    -> ('David'), ('Robert'), ('Adam'), ('John'), ('Jace');
Query OK, 10 rows affected

ข้อมูลทั้งหมด (Id 1-10)

+----+-----------+
| Id | FirstName |
+----+-----------+
|  1 | Chris     |
|  2 | Bob       |
|  3 | Sam       |
|  4 | Mike      |
|  5 | Carol     |
|  6 | David     |
|  7 | Robert    |
|  8 | Adam      |
|  9 | John      |
| 10 | Jace      |
+----+-----------+

คำสั่ง: ดึง Batch ที่ 2 (ข้าม 4 แถวแรก รับ 4 แถว)

mysql> SELECT * FROM DemoTable1514 LIMIT 4 OFFSET 4;

ผลลัพธ์ (แถวที่ 5-8)

+----+-----------+
| Id | FirstName |
+----+-----------+
|  5 | Carol     |
|  6 | David     |
|  7 | Robert    |
|  8 | Adam      |
+----+-----------+

สูตรคำนวณ OFFSET สำหรับหน้าเว็บ (Page Number เริ่มที่ 1)

OFFSET = (page_number - 1) * page_size
LIMIT = page_size

-- หน้า 1: LIMIT 10 OFFSET 0
-- หน้า 2: LIMIT 10 OFFSET 10
-- หน้า 3: LIMIT 10 OFFSET 20

⚠️ ปัญหาประสิทธิภาพ OFFSET ใหญ่ (Deep Pagination)

เมื่อ OFFSET ใหญ่มาก (เช่น หน้าที่ 10000) MySQL ต้องอ่านและทิ้งแถว 100,000 แถวก่อน → ช้า

แก้ไขด้วย Keyset Pagination (Seek Method)

-- แทน OFFSET ใช้ WHERE Id > last_seen_id
SELECT * FROM DemoTable1514 
WHERE Id > 4  -- Id สุดท้ายของหน้าก่อน
ORDER BY Id 
LIMIT 4;

ต้องมี Index บนคอลัมน์ ORDER BY (ที่นี่คือ PK)

MySQL 8.0: OFFSET ... ROWS FETCH NEXT ... ROWS ONLY (SQL Standard)

SELECT * FROM DemoTable1514
ORDER BY Id
OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY;