(MYSQL) Auswertung der Datenbank
Helmut Weber
- perl
Hallo SelfForum,
ich muss eine Datenbank auswerten, in der ca. 500.000 Einträge stehen.
Hier mein Quellcode:
my $year = $CGI->param('year');
my $month = $CGI->param('month');
my $entrys_month = $Config::DBH->selectrow_array( "SELECT COUNT(entry) FROM participant WHERE year(entry) = $year AND MONTH(entry) = $month " );
my @monatsliste = ();
for ( my $i = 1; $i <= 31; $i++) {
my $entrys = $Config::DBH->selectrow_array( "SELECT COUNT(entry) FROM participant WHERE YEAR(entry) = $year AND MONTH(entry) = $month AND DAYOFMONTH(entry) = $i " );
push @monatsliste, { VALUE => $i, ENTRYS => $entrys };
}
Ich möchte Auswerten, an welchem Tag im Monat wieviele Eintragungen gemacht worden sind, und diese per HTML anzeigen.
Mein Problem ist, das ich an die Grenze der maximalen Bearbeitungszeit komme, und das Skript abgebrochen wird. (Weit über 1 Minute).
Kann mir jemand einen Tipp geben, wie ich meine SQL-Abfrage optimieren kann?
Gruß
Helmut Weber
Halihallo Helmut
Kann mir jemand einen Tipp geben, wie ich meine SQL-Abfrage optimieren kann?
Benutzt du Indizies? - Wenn nein, hurtig, hurtig einen definiert und staunend über die
Abfragegeschwindigkeit.
Viele Grüsse
Philipp
Hallo Philipp,
Benutzt du Indizies? - Wenn nein, hurtig, hurtig einen definiert und staunend über die
Abfragegeschwindigkeit.
Danke für den Tipp!
Heißt das für mich, das ich für die Spalte "entry" einen Index anlegen muss und schon wird meine Abfragegeschwindigkeit besser?
Bisher hatte ich nur einen Index für die ID-Nummer des Eintrages (PRIMARY), wird aber für meine Abfrage nicht von Bedeutung sein.
Ich werde es mal ausprobieren...
Gruß
Helmut Weber
Halihallo Helmut
Danke für den Tipp!
Dass du den ja nie vergisst, der ist nämlich _zentral_ für Datenbanksysteme.
Heißt das für mich, das ich für die Spalte "entry" einen Index anlegen muss und schon wird meine Abfragegeschwindigkeit besser?
Exakt.
Bisher hatte ich nur einen Index für die ID-Nummer des Eintrages (PRIMARY), wird aber für meine Abfrage nicht von Bedeutung sein.
Ein Index auf den Primary bringt dir bei diese(r|n) Abfrage(n) gar nichts.
Viele Grüsse
Philipp
Halihallo Helmut
my @monatsliste = ();
for ( my $i = 1; $i <= 31; $i++) {
my $entrys = $Config::DBH->selectrow_array( "SELECT COUNT(entry) FROM participant WHERE YEAR(entry) = $year AND MONTH(entry) = $month AND DAYOFMONTH(entry) = $i " );
push @monatsliste, { VALUE => $i, ENTRYS => $entrys };
}
Tipp nummero dos:
Verwende GROUP BY MONTH(entry), YEAR(entry), DAYOFMONTH(entry)
und lass die for-Schleife im Script weg. Damit reduziert sich die Anzahl der Abfragen auf
zwei statt 32.
Viele Grüsse
Philipp
Halihallo Philipp
my @monatsliste = ();
for ( my $i = 1; $i <= 31; $i++) {
my $entrys = $Config::DBH->selectrow_array( "SELECT COUNT(entry) FROM participant WHERE YEAR(entry) = $year AND MONTH(entry) = $month AND DAYOFMONTH(entry) = $i " );
push @monatsliste, { VALUE => $i, ENTRYS => $entrys };
}
Verwende GROUP BY MONTH(entry), YEAR(entry), DAYOFMONTH(entry)
Korrektur: MONTH(entry) und YEAR(entry) gehören in die WHERE-Klausel, da sie staatischer
Natur sind (sie werden ja als Parameter des Scripts festgelegt). Bei meinem Vorschlag
hättest du jeden Tag einzeln, egal in welchem Jahr und Monat aufgelistet bekommen, dir
beliebt es ja nur nach dem Monat und Jahr, welche übergeben wurden.
Zudem wäre es ggf. sogar performanter, wenn du die einzelnen Tage aufsummierst und so die
Totale Anzahl Einträge für den gesamten Monat berechnest. So würde die Anzahl der
Abfragen auf eins reduziert und die Berechnung der ersten Query-Abfrage auf das
addieren von 31 Werten reduziert. Ob sich das jedoch lohnt oder nicht müsstest du mit
Benchmarks messen.
btw: was haben Datenbanken mit Perl zu tun?
Viele Grüsse
Philipp