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

Truy vấn MySQL với giới hạn và bù đắp lớn sẽ mất vĩnh viễn

LIMIT với độ lệch cực kỳ chậm trong hầu hết các cơ sở dữ liệu (Tôi đã tìm thấy một số tài liệu hiệu ứng này cho MySQL và tôi đang cố gắng tìm một bài báo thực sự tốt mà tôi đã đọc một thời gian trước giải thích điều này cho SQLite). Lý do là nó thường được triển khai một cái gì đó như thế này:

  1. Thực hiện tất cả lập kế hoạch truy vấn bình thường như thể LIMIT mệnh đề không có ở đó
  2. Xem qua kết quả cho đến khi chúng tôi nhận được chỉ mục bạn muốn
  3. Bắt đầu trả về kết quả

Điều này có nghĩa là gì nếu bạn thực hiện LIMIT 10000, 10 , nó sẽ được hiểu là:

  1. Tìm nạp 10.000 kết quả đầu tiên và bỏ qua chúng
  2. Cung cấp cho bạn 10 kết quả tiếp theo

Có một cách tối ưu hóa tầm thường mà ít nhất bạn có thể sử dụng chỉ mục cho 10.000 kết quả đầu tiên vì bạn không quan tâm đến giá trị của chúng, nhưng ngay cả trong trường hợp đó, cơ sở dữ liệu vẫn cần xem qua 10.000 giá trị chỉ mục trước khi cung cấp cho bạn 10 kết quả. Có thể có những tối ưu hóa hơn nữa có thể cải thiện điều này, nhưng trong trường hợp chung bạn không muốn sử dụng LIMIT với phần bù cho các giá trị lớn .

Cách hiệu quả nhất để xử lý phân trang mà tôi biết là theo dõi chỉ mục cuối cùng, vì vậy nếu trang một kết thúc ở id = 5 , sau đó thực hiện tiếp theo của bạn liên kết có WHERE id > 5 (với LIMIT x tất nhiên).

CHỈNH SỬA:Đã tìm thấy bài viết cho SQLite . Tôi thực sự khuyên bạn nên đọc phần này vì nó giải thích The Right Way ™ để thực hiện các công việc trong SQL. Vì những người sử dụng SQLite thực sự thông minh và các cơ sở dữ liệu khác có cùng vấn đề này, tôi giả sử MySQL triển khai điều này theo cách tương tự.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. LOAD DATA LOCAL INFILE bị cấm trong ... PHP

  2. Cách sử dụng nhiều cơ sở dữ liệu trong Laravel

  3. PHP, MYSQL Autocomplete không hoạt động

  4. LAST_INSERT_ID () luôn trả về 0 (RMySQL) - vấn đề kết nối riêng

  5. THAY THẾ ký tự dòng mới trong MYSql không hoạt động