Myslím, že většina problémů zde a v podobných otázkách pochází z nepochopení toho, jak MySQL (a další databáze) používá indexy pro řazení. Odpověď zní:MySQL nepoužívá indexy pro řazení, pouze umí číst data v pořadí indexu nebo v opačném směru. Pokud jste náhodou chtěli, aby byla data seřazena v pořadí aktuálně používaného indexu - máte štěstí, jinak bude výsledek seřazen (proto filesort in EXPLAIN)
To je pořadí celého výsledku většinou závisí na tom, která tabulka byla první ve spojení. A když se podíváte na svůj EXPLAIN, uvidíte, že spojení začíná od tabulky 'log_codes' (protože je mnohem menší).
V zásadě potřebujete složený index (partner_id, datum) na 'log_entries', krycí složený index (log_code, category_overview, log_desc) pro 'log_codes', změňte 'INNER JOIN' na 'STRAIGHT_JOIN', abyste vynutili objednávku spojení, a seřaďte podle 'date' DESC (tento index bude naštěstí také pokrývat).
UPD1 :Omlouvám se, špatně jsem zadal index pro první tabulku:měl by být (partner_id, log_code, date)
.
MySQL může buď přímo vydávat data, pokud souhlasíte s pořadím, ve kterém je získává, nebo vkládat data do dočasné tabulky, poté použít třídění a výstup. Když objednáváte podle pole z jakékoli jiné než první tabulky ve spojeních, musí MySQL třídit data (nejen výstup v pořadí podle indexu) a k řazení dat potřebuje dočasnou tabulku.
Pro výstup řádků 50000,25 MySQL stejně potřebuje načíst prvních 50000 a přeskočit je. Protože jsem vynechal sloupec v indexu, MySQL nejenom prohledala index, ale pro každou položku provedla další vyhledávání na disku pro log_code
hodnota. S krycím indexem by to mělo být mnohem rychlejší, protože všechna data lze načíst z indexu.
UPD2 :zkuste vynutit index:
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;