Đây là những gì tôi đã làm và giảm tổng thời gian thực hiện xuống 10.
Những gì tôi nhận ra trong kế hoạch thực thi của truy vấn ban đầu của tôi là nó đang sử dụng filesort để sắp xếp tất cả các kết quả và bỏ qua các chỉ mục. Đó là một chút lãng phí.
Cơ sở dữ liệu thử nghiệm của tôi:5 bản ghi M, kích thước 20 GB. cấu trúc bảng giống như trong câu hỏi
Thay vì nhận trực tiếp blobCol trong truy vấn đầu tiên, trước tiên tôi lấy giá trị 'tên' cho đầu mỗi trang. Chạy truy vấn này vô thời hạn cho đến khi nó trả về 0 kết quả. Mỗi lần, hãy thêm kết quả vào danh sách
SELECT name
FROM my_table
where id = <anyId> // I use the id column for partitioning so I need this here
order by name
limit <pageSize * pageNumber>, 1
Số trang sin chưa được biết trước đó, bắt đầu bằng giá trị 0 và tiếp tục tăng cho đến khi truy vấn trả về giá trị rỗng. Bạn cũng có thể thực hiện đếm chọn (*) nhưng bản thân việc đó có thể mất nhiều thời gian và sẽ không giúp tối ưu hóa bất kỳ điều gì. Mỗi truy vấn mất khoảng 2 giây để chạy khi số trang vượt quá ~ 60.
Đối với tôi, kích thước trang là 5000 vì vậy tôi có danh sách các chuỗi 'tên' ở vị trí 0, 5001, 10001, 15001, v.v. Số lượng trang hóa ra là 1000 và việc lưu trữ danh sách 1000 kết quả trong bộ nhớ không hề đắt.
Bây giờ, hãy lặp lại danh sách và chạy truy vấn này
SELECT blobCol
FROM my_table
where name >= <pageHeader>
and name < <nextPageHeader>
and city="<any string>"
and id= 1
Điều này sẽ chạy N lần, trong đó N =kích thước của danh sách đã thu được trước đó. Vì 'tên' là cột khóa chính và 'thành phố' cũng được lập chỉ mục, EXPLAIN cho thấy rằng phép tính này được thực hiện trong bộ nhớ bằng cách sử dụng chỉ mục.
Giờ đây, mỗi truy vấn mất 1 giây để chạy, thay vì 30 - 40 như ban đầu. Vì vậy, kết hợp thời gian xử lý trước là 2 giây trên mỗi trang, tổng thời gian trên mỗi trang là 3-4 giây thay vì 30-40.
Nếu có ai có giải pháp tốt hơn hoặc nếu có điều gì đó không ổn với giải pháp này, vui lòng cho tôi biết