Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

mySQL - Phân trang các hàng đã lọc

Bạn không thể biết id đầu tiên trên một trang nhất định là gì, vì số id không nhất thiết phải theo thứ tự. Nói cách khác, có thể có khoảng trống trong trình tự, vì vậy các hàng trên trang thứ năm trong số 100 hàng không nhất thiết phải bắt đầu ở id 500. Chẳng hạn, nó có thể bắt đầu từ id 527, Không thể biết được.

Nói một cách khác: id là một giá trị, không phải số hàng.

Một giải pháp khả thi nếu khách hàng của bạn đang tiến qua các trang theo thứ tự tăng dần là mỗi yêu cầu REST tìm nạp dữ liệu, lưu ý điều lớn nhất giá trị id trên trang đó, sau đó sử dụng giá trị đó trong tiếp theo Yêu cầu REST để nó truy vấn các giá trị id lớn hơn.

SELECT ... FROM ... WHERE filterKey = filterValue 
AND id > id_of_last_match_of_previous_page

Nhưng nếu yêu cầu REST của bạn có thể tìm nạp bất kỳ trang ngẫu nhiên nào, thì giải pháp này không hoạt động. Nó phụ thuộc vào việc bạn đã tìm nạp trang trước.

Một giải pháp khác là sử dụng LIMIT <x> OFFSET <y> cú pháp. Điều này cho phép bạn yêu cầu bất kỳ trang tùy ý nào. LIMIT <y>, <x> hoạt động giống nhau, nhưng vì lý do nào đó x và y bị đảo ngược ở hai dạng cú pháp khác nhau, vì vậy hãy ghi nhớ điều đó.

Sử dụng LIMIT...OFFSET không hiệu quả lắm khi bạn yêu cầu một trang có nhiều trang trong kết quả. Giả sử bạn yêu cầu trang thứ 5.000. MySQL phải tạo kết quả ở phía máy chủ gồm 5.000 trang, sau đó loại bỏ 4.999 trang trong số đó và trả lại trang cuối cùng trong kết quả. Xin lỗi, nhưng đó là cách nó hoạt động.

Nhận xét lại của bạn:

Bạn phải hiểu rằng WHERE áp dụng các điều kiện về giá trị trong các hàng, nhưng các trang được xác định bởi vị trí hàng. Đây là hai cách xác định hàng khác nhau!

Nếu bạn có một cột được đảm bảo là số hàng , thì bạn có thể sử dụng giá trị đó như một vị trí hàng. Bạn thậm chí có thể đặt một chỉ mục trên đó hoặc sử dụng nó làm khóa chính.

Nhưng các giá trị khóa chính có thể thay đổi và có thể không liên tiếp, ví dụ:nếu bạn cập nhật hoặc xóa các hàng, hoặc khôi phục một số giao dịch, v.v. Đánh số lại các giá trị khóa chính là một ý tưởng tồi vì các bảng khác hoặc dữ liệu bên ngoài có thể tham chiếu đến các giá trị khóa chính.

Vì vậy, bạn có thể thêm một cột khác không khóa chính, nhưng chỉ một số hàng.

ALTER TABLE MyTable ADD COLUMN row_number BIGINT UNSIGNED, ADD KEY (row_number);

Sau đó điền các giá trị khi bạn cần đánh số lại các hàng.

SET @row := 0;
UPDATE MyTable SET row_number = (@row := @row + 1) ORDER BY id;

Ví dụ:bạn sẽ phải đánh số lại các hàng nếu bạn xóa một số hàng. Sẽ không hiệu quả nếu làm điều này thường xuyên, tùy thuộc vào kích thước của bảng.

Ngoài ra, các chèn mới không thể tạo các giá trị số hàng chính xác mà không khóa bảng. Điều này là cần thiết để ngăn chặn các điều kiện về chủng tộc.

Nếu bạn có đảm bảo rằng row_number là một chuỗi các giá trị liên tiếp, sau đó nó vừa là giá trị vừa là vị trí hàng, vì vậy bạn có thể sử dụng nó để tra cứu chỉ mục hiệu suất cao cho bất kỳ trang hàng tùy ý nào.

SELECT * FROM MyTable WHERE row_number BETWEEN 401 AND 500;

Ít nhất là cho đến khi dãy số hàng tiếp theo bị nghi ngờ do xóa hoặc chèn mới.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hiệu suất của truy vấn trên cột Boolean được lập chỉ mục so với cột Ngày giờ

  2. Làm cách nào để nhập bảng từ MySQL sang Hive bằng Java?

  3. Sự cố với hiển thị dữ liệu MySQL trên Android studio bằng cách sử dụng volley

  4. Lưu dữ liệu ngoại tuyến trước khi đăng

  5. MySQL:truy vấn con HOẶC hợp nhất?