Myślę, że większość problemów tutaj iw podobnych pytaniach wynika z niezrozumienia, w jaki sposób MySQL (i inne bazy danych) używa indeksów do sortowania. Odpowiedź brzmi:MySQL nie używa indeksów do sortowania, może po prostu czytać dane w kolejności indeksu lub w przeciwnym kierunku. Jeśli zdarzyło Ci się chcieć uporządkować dane w kolejności aktualnie używanego indeksu - masz szczęście, w przeciwnym razie wynik zostanie posortowany (stąd sortowanie plików w EXPLAIN)
To znaczy kolejność całego wyniku zależy głównie od tego, która tabela była pierwsza w łączeniu. A jeśli spojrzysz na swoje EXPLAIN, zobaczysz, że łączenie zaczyna się od tabeli „log_codes” (ponieważ jest znacznie mniejsza).
Zasadniczo potrzebujesz indeksu złożonego (partner_id, date) na 'log_entries', obejmującego indeks złożony (log_code, category_overview, log_desc) dla 'log_codes', zmień 'INNER JOIN' na 'STRAIGHT_JOIN', aby wymusić kolejność łączenia, i uporządkuj według „daty” DESC (ten indeks na szczęście również obejmuje).
UPD1 :Przepraszam, błędnie wpisałem indeks dla pierwszej tabeli:powinien to być (partner_id, log_code, date)
.
MySQL może albo bezpośrednio wyprowadzać dane, o ile zgadzasz się z kolejnością, w jakiej je pobiera, lub umieszczać dane w tabeli tymczasowej, następnie sortować i wyprowadzać dane. Kiedy porządkujesz według pola z dowolnej tabeli, która nie jest pierwszą w złączeniach, MySQL musi sortować dane (a nie tylko wyprowadzać dane w kolejności indeksu) i do sortowania danych potrzebuje tabeli tymczasowej.
Aby wyprowadzić wiersze 50000,25, MySQL i tak musi pobrać pierwsze 50000 i je pominąć. Ponieważ przegapiłem kolumnę w indeksie, MySQL nie tylko zeskanował indeks, ale dla każdego elementu wykonał dodatkowe wyszukiwanie na dysku dla log_code
wartość. Z indeksem pokrywającym, który powinien być znacznie szybszy, ponieważ wszystkie dane można pobrać z indeksu.
UPD2 :spróbuj wymusić indeks:
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;