Programmieren - alles kontrollieren 4.935 Themen, 20.621 Beiträge

MySQL - Copying to tmp table

hansapark / 2 Antworten / Flachansicht Nickles

Hallo. Ich habe mir meine beiden langsamsten MySQL-Queries in der Konsole angesehen und gesehen, dass die meiste Zeit bei:

| Copying to tmp table | 0.000263 |
| Copying to tmp table | 0.052237 |
| Sorting result | 0.000035 |

vergeht. Was hat es mit den tmp tables auf sich? Es war mir nicht bewusst, dass sowas überhaupt passiert. Und kann ich den Query anpassen, um das zu verbessern?

Z.Bsp. diesen:

select `pics`.*, `users`.`username`, `users`.`displayname` from `pics` left join `users` on `users`.`id` = `pics`.`user_id` order by RAND() asc limit 4;

Da werden 4 Zufallsbilder geladen, und username und displayname dazu geholt mit join.

Aber am join sollte es nicht liegen, oder?

Indizes habe ich diese:

pics:

PRIMARY id
UNIQUE created_at
INDEX user_id
INDEX location

und bei users:

PRIMARY id
UNIQUE username

danke für einen tipp.

bei Antwort benachrichtigen
Borlander hansapark „MySQL - Copying to tmp table“
Optionen
Was hat es mit den tmp tables auf sich?

Es muss zur Verarbeitung der Abfrage noch eine temporäre Zwischentabelle erzeugt werden. Bei kleinen Ergebnisemengen passt diese in den Arbeitsspeicher. Wenn das nicht mehr der Fall ist, dann landet die auch auf Platte. Das ist dann wirklich nicht mehr schön.

Ich würde hier mal auf das ORDER BY RAND() als Verursacher tippen.

Nutze EXPLAIN um Dir mal genauer anzuschauen wie MySQL die Abfrage verarbeitet.

Wenn sichergestellt ist, dass zu jeder pics.user_id auch ein users.id existiert, dann könntest Du schon mal den Umfang des Joins deutlich reduzieren:

select p.*, username, displayname
FROM (SELECT * FROM `pics` order by RAND() limit 4) AS p
LEFT JOIN users ON users.id = p.user_id;

ORDER BY RAND() ist generell keine besonders schöne Lösung. Mal einen Blick auf mögliche Alternativen werfen kann sicherlich nicht schaden: http://www.warpconduit.net/2011/03/23/selecting-a-random-record-using-mysql-benchmark-results/ (ohne Anspruch auf Vollständigkeit)

bei Antwort benachrichtigen