Vấn đề là MySQL chỉ sử dụng một chỉ mục khi thực hiện truy vấn. Nếu bạn thêm một chỉ mục mới sử dụng 3 trường trong WHERE
của bạn , nó sẽ tìm các hàng nhanh hơn.
ALTER TABLE `adverts` ADD INDEX price_status_approved(`price`, `status`, `approved`);
Theo tài liệu MySQL ĐẶT HÀNG BẰNG Tối ưu hóa :
Đây là những gì sẽ xảy ra trong trường hợp của bạn. Như kết quả của EXPLAIN
cho chúng tôi biết, trình tối ưu hóa sử dụng khóa price
để tìm các hàng. Tuy nhiên, ORDER BY
nằm trên trường date_updated
không thuộc về khóa price
.
Để tìm các hàng nhanh hơn VÀ sắp xếp các hàng nhanh hơn, bạn cần thêm chỉ mục chứa tất cả các trường được sử dụng trong WHERE
và trong ORDER BY
mệnh đề:
ALTER TABLE `adverts` ADD INDEX status_approved_date_updated(`status`, `approved`, `date_updated`);
Trường được sử dụng để sắp xếp phải ở vị trí cuối cùng trong chỉ mục. Sẽ vô ích nếu bao gồm price
trong chỉ mục, vì điều kiện được sử dụng trong truy vấn sẽ trả về một dải giá trị.
Nếu EXPLAIN
vẫn cho thấy rằng nó đang sử dụng filesort, bạn có thể thử buộc MySQL sử dụng chỉ mục bạn chọn:
SELECT adverts.*
FROM adverts
FORCE INDEX(status_approved_date_updated)
WHERE price >= 0
AND adverts.status = 1
AND adverts.approved = 1
ORDER BY date_updated DESC
LIMIT 19990, 10
Thông thường không cần thiết phải ép buộc một chỉ mục, vì trình tối ưu hóa MySQL thường thực hiện lựa chọn chính xác. Nhưng đôi khi nó đưa ra một lựa chọn tồi, hoặc không phải là lựa chọn tốt nhất. Bạn sẽ cần chạy một số thử nghiệm để xem liệu nó có cải thiện hiệu suất hay không.