Mailinglisten-Archive |
Sven wrote: > Hallo > > Ich habe eine Abfrage, die je mehr Ergebnisse sie liefert, weit mehr als 4 > Sekunden dauern kann. Das muss doch irgendwie zu optimieren sein. > Mir fällt allerdings nichts mehr dazu ein. > > Hier die Abfrage: > SELECT kfz_firmen.f_id, kfz_firmen.firma, kfz_firmen.strasse, kfz_firmen.plz, > kfz_firmen.ort, kfz_firmen.accountart, kfz_firmen.akin > FROM kfz_firmen, kfz_automarke, kfz_region, kfz_service > LEFT JOIN kfz_zu_af ON ( > kfz_firmen.f_id = kfz_zu_af.f_id AND kfz_automarke.a_id = kfz_zu_af.a_id) > LEFT JOIN kfz_zu_rf ON ( > kfz_firmen.f_id = kfz_zu_rf.f_id AND kfz_region.r_id = kfz_zu_rf.r_id ) > LEFT JOIN kfz_zu_sf ON ( > kfz_firmen.f_id = kfz_zu_sf.f_id AND kfz_service.s_id = kfz_zu_sf.s_id ) > WHERE kfz_firmen.akin = '1' AND kfz_automarke.akin = '1' AND > kfz_region.akin = '1' AND kfz_service.akin = '1' AND > kfz_service.s_id = '25' AND kfz_zu_sf.s_id = '25' > GROUP BY kfz_firmen.firma, kfz_firmen.strasse > ORDER BY kfz_firmen.accountart, kfz_firmen.firma > LIMIT 0 , 10 > > Anmerkungen dazu: > Es gibt 4 Tabellen mit Hauptinhalten, wobei sich alles auf die Tabelle > "kfz_firmen" bezieht. > 3 Tabellen (kfz_zu_af, kfz_zu_rf, kfz_zu_sf) beinhalten die Verknüpfungen der > Tabellen kfz_automarke, kfz_region und kfz_service mit der Tabelle > kfz_firmen. > Die Verknüpfungstabellen sehen so aus (Beispiel kfz_zu_af): > af_id | a_id | f_id > af_id - Primary > a_id - Index > f_id - Index > > Die akin-Spalten sind vom Typ "enum" und beinhalten nur 1 oder 0. > > So, und dann hab ich zu dieser Abfrage noch eine EXPLAIN-Ausgabe (Erzeugt mit > phpMyAdmin): > > +---------------+-------+---------------+---------+---------+ > | table | type | possible_keys | key | key_len | > +---------------+-------+---------------+---------+---------+ > | kfz_service | const | PRIMARY,akin | PRIMARY | 4 | > | kfz_firmen | range | akin | akin | 1 | > | kfz_automarke | ALL | akin | NULL | NULL | > | kfz_zu_af | ref | a_id,f_id | a_id | 4 | > | kfz_region | ALL | akin | NULL | NULL | > | kfz_zu_rf | ALL | f_id,r_id | NULL | NULL | > | kfz_zu_sf | ref | f_id,s_id | f_id | 4 | > +---------------+-------+---------------+---------+---------+ > > +---------------+-------------------+------+--------------------------------+ > | table | ref | rows | Extra | > +---------------+-------------------+------+--------------------------------+ > | kfz_service | const | 1 | Using temporary; Using filesort| > | kfz_firmen | NULL | 132 | Using where | > | kfz_automarke | NULL | 24 | Using where | > | kfz_zu_af | kfz_automarke.a_id| 12 | | > | kfz_region | NULL | 30 | Using where | > | kfz_zu_rf | NULL | 25 | | > | kfz_zu_sf | kfz_firmen.f_id | 12 | Using where | > +---------------+-------------------+------+--------------------------------+ > > Wo kann man hier mit einer Optimierung ansetzen? > du hast vergessen zu sagen WAS die Abfrage denn liefern soll? SELECT kfz_firmen.f_id, kfz_firmen.firma, kfz_firmen.strasse, kfz_firmen.plz, kfz_firmen.ort, kfz_firmen.accountart, kfz_firmen.akin FROM kfz_service LEFT JOIN kfz_zu_sf ON kfz_service.s_id = kfz_zu_sf.s_id LEFT JOIN kfz_firmen ON kfz_firmen.f_id = kfz_zu_sf.f_id LEFT JOIN kfz_zu_af ON kfz_firmen.f_id = kfz_zu_af.f_id LEFT JOIN kfz_automarke ON kfz_automarke.a_id = kfz_zu_af.a_id LEFT JOIN kfz_zu_rf ON kfz_firmen.f_id = kfz_zu_rf.f_id LEFT JOIN kfz_region, ON kfz_region.r_id = kfz_zu_rf.r_id WHERE kfz_service.s_id = '25' AND kfz_service.akin = '1' AND kfz_automarke.akin = '1' AND kfz_region.akin = '1' AND kfz_firmen.akin = '1' GROUP BY kfz_firmen.f_id ORDER BY kfz_firmen.accountart, kfz_firmen.firma LIMIT 0, 10 ... mhm auf jeden fall sollten deine ORDER BY - Spalten auch im index sein!!! kfz_firmen INDEX(f_id, accountart, firma) ... außerdem sollte die allererste Tabelle, also die direkt nach dem fROM sollte die sein die die wenigsten Datansätze zurückliefert, in diesem Fall wohl kfz_service ... das GOUP BY sollte natürlich auch auf NUR auf indizierte Spalten angweandt werden!!! Grundsätzlich: es sollten möglichst ALLE Saplten die in WHERE, ORDER BY oder GROUP BY verwendet werden in einem Index vorkommen 'Using temporary; Using filesort' ist das Schlechteste was überhaupt da stehen kann bei EXPLAIN (hast du ein index auf kfz_service.s_id ???) hast die Indizes auf die akin-Spalten? in kfz_service ein Index auf s_id,akin -- Sebastian Mendel *www.warzonez.de* www.sebastianmendel.de | www.tekkno4u.de | www.nofetish.com
php::bar PHP Wiki - Listenarchive