Erklärung für Query-Dauer?

Hallo,

ich hab hier eine Abfrage, die aus allen Wettbewerben weltweit die Top30 Torschützen der aktuellen Saison (2006/2007 und 2006) ermittelt.

Leider braucht dieser Query 12 Sekunden für die Ausführung. Hab dann ein wenig rum probiert und die Zeit gemessen. Dabei gabs dann einige merkwürdige Ergebnisse und ich kann mir nicht erklären wie diese zustande kommen.

Hier mal mein Query:

select distinct spielerbericht.spieler_id, count(spielerbericht.id) as spiele, sum(spielerbericht.spielzeit) as minuten, sum(spielerbericht.tore) as tore_gesamt
from spielerbericht
inner join spielplan on spielplan.id = spielerbericht.begegnung_id
inner join tabdef on tabdef.id = spielplan.tabdef_id
where
(
tabdef.liga_id = 1
)
and
(
tabdef.nation_id = 1 or tabdef.nation_id = 21 or tabdef.nation_id = 32 or tabdef.nation_id = 51
)
and
(
tabdef.saison = ‚2006/2007‘ or tabdef.saison = ‚2006‘
)
group by spielerbericht.spieler_id
order by tore_gesamt desc limit 30

Erläuterung:

  • Tabelle Spielerbericht = Für jeden Einsatz eines Spielers gibts da einen Datensatz
  • Tabelle Spielplan = Begegnungen, 1 zu n mit Spielerbericht
    Tabelle Tabdef = Wettbewerbe, 1 zu n mit Spielplan

Ergebnis:
Dieser Query braucht also 12 Sekunden. Hab jetzt einige kleine Veränderungen vorgenommen mit folgenden Ergebnissen:

  1. Anstatt nach 06/07 + 06 hab ich nur nach einer Saison selectiert. Daraufhin brauchte die Abfrage nur noch 0,3 Sekunden. Dabei ist es egal welche Saison ich da nehme. Sobald eine zweite dazu kommt bin cih wieder bei 12 Sekunden. Nehm ich allerdings noch eine dritte, vierte oder 5 Saison dazu braucht der Query trotzden nur 12 Sekunde. Es gibt nur den Zeitsprung von einer auf zwei.

  2. Genau so verhält es sich bei der Länderauswahl (tabdef.nation_id). Bei einem Land dauerts wieder 0,3 Sekunden, sobald ein zweites, drittes oder viertes Land dazu kommt bin ich wieder bei 12 Sekunden.

  3. Genau andes rum ist es bei der Ligaauswahl. Wenn ich ausgehend vom obigen Query eine oder mehrere weitere Ligen dazu nehme braucht der Query anstatt 12 Sekunden nur noch 0,3 Sekunden.

Hat jemand ne Idee wie diese Ergebnisse zustande kommen? Bin auch dankbar für einige Tips die den Query schneller machen.

Danke, Christian

Hallo,

erst mal solltest du sagen, welche DB du benutzt.

Anscheinend hat der Optimizer Schwierigkeiten den SELECT einzuordnen. Du kannst ihm helfen:

unter Oracle geht das so:

  1. dem Optimizer auf COST umstellen mit
    ANALYZE TABLE xxx COMPUTE STATISTICS FOR TABLE;
    für alle Tabellen.
  2. Indexe erstellen:
    CREATE INDEX xxx ON spielerbericht (begegnug_id)
    usw für alle nicht-Schlüsselattribute in der WHERE Bedingung.

Das sollte helfen.

Ganz schnell geht es mit einem Materialized View.

Gruß

Peter

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Peter,

danke (mal wieder) für deine Hilfe.

Ich verwende MySQL 4.x. Alle Attribute in der where Klausel sind bereits indiziert.

Ich hab jetzt zusätzlich noch die Tabelle Spieler per inner join verknüpft (inner join spieler on spieler.id = spielerbericht.spieler_id) und dann nach spieler.id guppiert. Jetzt dauert der Query auch nur 0,3 Sekunden.

Das erklärt aber noch niht die Sprünge von 0,3 auf 12 Sekunden.

Christian

Hi,

Ich verwende MySQL 4.x. Alle Attribute in der where Klausel
sind bereits indiziert.

Deswegen muss der Optimizer die Indices noch lange nicht benutzen. Gerade MySQL ist da manchmal nicht sehr optimal. (Um es vorsichtig auszudrücken)

Setze einfach mal ein EXPLAIN vor das Select statement. Dann sagt dir MySQL wie die Abfrage ausgeführt wird. Mit „force index“ kannst du dann MySQL zwingen eine bestimmten Index zu nehmen.

Gruss
Quaser