Potrzebujesz indeksu złożonego w tabeli przecięcia:
ALTER TABLE instruments_tools ADD KEY (id_instrument, id_tool);
Kolejność kolumn w tym indeksie jest ważna!
Mamy nadzieję, że złączenia rozpoczną się od tabeli instrumentów, a następnie wyszuka pasujący wpis indeksu w indeksie złożonym na podstawie id_instrument. Następnie po znalezieniu tego wpisu w indeksie ma za darmo powiązane narzędzie id_tool. Więc nie musi w ogóle czytać tabeli instrument_tools, wystarczy tylko odczytać wpis indeksu. Powinno to dać komentarz „Using index” w EXPLAIN dla tabeli instrumenty_narzędzia.
To powinno pomóc, ale nie możesz uniknąć tabeli tymczasowej i sortowania plików, ponieważ kolumny, według których grupujesz i sortujesz, nie mogą korzystać z indeksu.
Możesz spróbować sprawić, by MySQL unikał zapisywania tabeli tymczasowej na dysk, zwiększając rozmiar pamięci, której może używać dla tabel tymczasowych:
mysql> SET GLOBAL tmp_table_size = 256*1024*1024; -- 256MB
mysql> SET GLOBAL max_heap_table_size = 256*1024*1024; -- 256MB
Ta liczba to tylko przykład. Nie mam pojęcia, jak duży musiałby być stół tymczasowy w twoim przypadku.