AllesMeins: /MySQL: JOIN optimieren

Beitrag lesen

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)