Các chỉ số không nhất thiết phải cải thiện hiệu suất. Để hiểu rõ hơn điều gì đang xảy ra, sẽ hữu ích nếu bạn bao gồm explain
cho các truy vấn khác nhau.
Dự đoán tốt nhất của tôi là bạn có một chỉ mục trong id_state
hoặc thậm chí id_state, id_mp
có thể được sử dụng để đáp ứng where
mệnh đề. Nếu vậy, truy vấn đầu tiên không có order by
sẽ sử dụng chỉ mục này. Nó sẽ khá nhanh. Ngay cả khi không có chỉ mục, điều này yêu cầu quét tuần tự các trang trong orders
bảng, vẫn có thể khá nhanh.
Sau đó, khi bạn thêm chỉ mục vào creation_date
, MySQL quyết định sử dụng chỉ mục đó thay thế cho order by
. Điều này yêu cầu đọc từng hàng trong chỉ mục, sau đó tìm nạp trang dữ liệu tương ứng để kiểm tra where
điều kiện và trả về các cột (nếu có sự trùng khớp). Việc đọc này rất kém hiệu quả, bởi vì nó không theo thứ tự "trang" mà là theo chỉ mục được chỉ định. Đọc ngẫu nhiên có thể khá kém hiệu quả.
Tệ hơn nữa, mặc dù bạn có limit
, bạn vẫn phải đọc toàn bộ bảng vì toàn bộ tập kết quả là cần thiết. Mặc dù bạn đã lưu một loại trên 38 bản ghi, nhưng bạn đã tạo ra một truy vấn hàng loạt không hiệu quả.
Nhân tiện, tình huống này trở nên tồi tệ hơn đáng kể nếu orders
bảng không phù hợp với bộ nhớ có sẵn. Sau đó, bạn có một điều kiện gọi là "thrashing", trong đó mỗi bản ghi mới có xu hướng tạo ra một lần đọc I / O mới. Vì vậy, nếu một trang có 100 bản ghi trên đó, thì trang đó có thể phải được đọc 100 lần.
Bạn có thể làm cho tất cả các truy vấn này chạy nhanh hơn bằng cách có chỉ mục trên orders(id_state, id_mp, creation_date)
. where
mệnh đề sẽ sử dụng hai cột đầu tiên và order by
sẽ sử dụng cuối cùng.