Tôi nghĩ, hầu hết các vấn đề ở đây và trong các câu hỏi tương tự đến từ việc hiểu sai cách MySQL (và các cơ sở dữ liệu khác) sử dụng các chỉ mục để sắp xếp. Câu trả lời là:MySQL không sử dụng các chỉ mục để sắp xếp, nó chỉ có thể đọc dữ liệu theo thứ tự của một chỉ mục hoặc theo hướng ngược lại. Nếu bạn tình cờ muốn dữ liệu được kiểm tra theo thứ tự của chỉ mục hiện đang sử dụng - thì bạn thật may mắn, nếu không kết quả sẽ được sắp xếp (do đó tệp sắp xếp trong GIẢI THÍCH)
Đó là thứ tự của toàn bộ kết quả chủ yếu phụ thuộc vào bảng nào là bảng đầu tiên tham gia. Và nếu bạn nhìn vào GIẢI THÍCH của mình, bạn sẽ thấy rằng tham gia bắt đầu từ bảng 'log_codes' (vì nó nhỏ hơn nhiều).
Về cơ bản, những gì bạn cần là một chỉ mục tổng hợp (partner_id, ngày tháng) trên 'log_entries', một chỉ mục tổng hợp bao trùm (log_code, category_overview, log_desc) cho 'log_codes', thay đổi 'INNER JOIN' thành 'STRAIGHT_JOIN' để buộc thứ tự tham gia, và đặt hàng theo 'ngày tháng' DESC (chỉ số này cũng sẽ bao gồm).
UPD1 :Tôi xin lỗi, tôi đã gõ nhầm chỉ mục cho bảng đầu tiên:nó phải là (partner_id, log_code, date)
.
MySQL có thể trực tiếp xuất dữ liệu miễn là bạn đồng ý với thứ tự mà nó nhận được hoặc đặt dữ liệu vào một bảng tạm thời, áp dụng sắp xếp và xuất sau đó. Khi bạn sắp xếp theo một trường từ bất kỳ bảng nào không phải bảng đầu tiên trong các phép nối, MySQL phải sắp xếp dữ liệu (không chỉ xuất theo thứ tự của một chỉ mục) và để sắp xếp dữ liệu, nó cần một bảng tạm thời.
Để xuất các hàng 50000,25 MySQL vẫn cần tìm nạp 50000 đầu tiên và bỏ qua chúng. Vì tôi đã bỏ lỡ một cột trong chỉ mục, nên MySQL không chỉ lướt qua chỉ mục mà còn đối với mỗi mục, thực hiện bổ sung khi tra cứu đĩa cho log_code
giá trị. Với chỉ mục bao trùm sẽ nhanh hơn nhiều, vì tất cả dữ liệu có thể được tìm nạp từ chỉ mục.
UPD2 :cố gắng buộc chỉ mục:
SELECT log_entries.date, log_codes.log_desc
FROM log_entries FORCE INDEX (IX_partner_code_date)
STRAIGHT_JOIN log_codes
ON log_codes.log_code = log_entries.log_code
WHERE log_entries.partner_id = 1
AND log_codes.category_overview = 1
ORDER BY log_entries.date DESC;