Hai bisogno di un indice composto sulla tabella di intersezione:
ALTER TABLE instruments_tools ADD KEY (id_instrument, id_tool);
L'ordine delle colonne in quell'indice è importante!
Quello che speri è che i join inizino con la tabella dello strumento, quindi cerchino la voce dell'indice corrispondente nell'indice composto basato su id_instrument. Quindi, una volta trovata quella voce di indice, ha il relativo id_tool gratuitamente. Quindi non deve leggere affatto la tabella instrument_tools, deve solo leggere la voce dell'indice. Questo dovrebbe fornire il commento "Uso dell'indice" in EXPLAIN per la tabella instruments_tools.
Questo dovrebbe aiutare, ma non puoi evitare la tabella temporanea e il filesort, perché le colonne per cui stai raggruppando e ordinando non possono utilizzare un indice.
Puoi provare a fare in modo che MySQL eviti di scrivere la tabella temporanea su disco aumentando la dimensione della memoria che può utilizzare per le tabelle temporanee:
mysql> SET GLOBAL tmp_table_size = 256*1024*1024; -- 256MB
mysql> SET GLOBAL max_heap_table_size = 256*1024*1024; -- 256MB
Quella cifra è solo un esempio. Non ho idea di quanto dovrebbe essere grande per la tabella temporanea nel tuo caso.