Ich bräuchte etwas Hilfe beim optimieren eines Querys, der sehr lange läuft (~30 Sekunden). Folgende Situation - ich habe eine Tabelle userTitel und eine Tabelle titel. Nun führe ich folgenden Query aus:
SELECT titel.titelUrl, playcount, score, laenge FROM userTitel LEFT JOIN titel ON titel.titelUrl = userTitel.titelUrl WHERE userName = 'XXXX'
Wie gesagt, dieser läuft ungefähr 30 Sekunden (Anfragen auf einer Tabelle alleine - also ohne JOIN - brauchen etwa 0,2 Sekunden). Nun sind beides recht große Tabellen, die Frage ist ob sich da trotzdem noch etwas optimieren lässt. Die Result-Sets sind im Schnitt etwa 4000 Ergebnisse groß - da ich ja auf der "linken"-Tabelle selektiere müssen auch nur 4000 Joins durchgeführt werden.
Also, eure Meinung: Kann man an der Laufzeit noch was machen? Oder sind die 30 Sekunden eine realistische Laufzeit auf einem halbwegs aktuellen Desktop-Rechner?
Details zu den Tabellen:
mysql> DESC titel;
+-----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+-------+
| titelUrl | varchar(255) | NO | PRI | NULL | |
| titelName | varchar(255) | NO | | NULL | |
| artistUrl | varchar(255) | NO | MUL | NULL | |
| laenge | mediumint(9) | NO | | NULL | |
| tagSkip | enum('0','1') | NO | | NULL | |
+-----------+---------------+------+-----+---------+-------+
(etwa 2,7 Millionen Einträge)
mysql> DESC userTitel;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| userName | varchar(255) | NO | MUL | NULL | |
| titelUrl | varchar(255) | NO | MUL | NULL | |
| playcount | int(11) | NO | | NULL | |
| score | float | NO | | NULL | |
+-----------+--------------+------+-----+---------+-------+
(etwa 24 Millionen Einträge)
mysql> EXPLAIN SELECT titel.titelUrl, playcount, score, laenge FROM userTitel LEFT JOIN titel ON titel.titelUrl = userTitel.titelUrl WHERE userTitel.userName = 'XXXX';
+----+-------------+-----------+--------+---------------+----------+---------+---------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+--------+---------------+----------+---------+---------------------------------+------+-------------+
| 1 | SIMPLE | userTitel | ref | userName | userName | 767 | const | 9160 | Using where |
| 1 | SIMPLE | titel | eq_ref | PRIMARY | PRIMARY | 767 | diplomarbeit.userTitel.titelUrl | 1 | |
+----+-------------+-----------+--------+---------------+----------+---------+---------------------------------+------+-------------+
mysql> show profile for query 3;
+--------------------------------+-----------+
| Status | Duration |
+--------------------------------+-----------+
| starting | 0.000052 |
| checking query cache for query | 0.000305 |
| Opening tables | 0.000038 |
| System lock | 0.000010 |
| Table lock | 0.000113 |
| init | 0.000076 |
| optimizing | 0.000035 |
| statistics | 0.055601 |
| preparing | 0.000080 |
| executing | 0.000008 |
| Sending data | 27.786912 |
| end | 0.000025 |
| query end | 0.000005 |
| freeing items | 0.000083 |
| storing result in query cache | 0.000010 |
| logging slow query | 0.000003 |
| logging slow query | 0.011079 |
| cleaning up | 0.000026 |
+--------------------------------+-----------+
(was genau ist "sending data" - es hat jedenfalls nichts mit der Größe der zurückgelieferten Daten zu tun)