phpbar.de logo

Mailinglisten-Archive

Select und Maximalwert

Select und Maximalwert

Alexander Friess mysql_(at)_lists.phpcenter.de
Tue, 15 May 2001 08:39:18 +0200


Hi Andre,

> > Wenn Du immer das kleinste Datum haben willst, dann gruppieren:
> > "select min(validFrom), kunde group by kunde"
> > So erhälst Du eine Liste mit genau einem EINTRAG PRO KUNDE.
>
> Das hier kling sogar so gut, daß ich mein Provisorium mit dem Zähler
> (wohl) nicht brauche! Das muß ich mal prüfen. Primärschlüssel ist
> "Kunde", eine Kurzbezeichnung des Kundennames.
Dann vergiß das mit "leeren" Feld validTo!

>
> >
> > Höchsten Zähler analog:
> > "select max(zaehler), kunde group by kunde"
> > So erhälst Du eine Liste mit genau einem EINTRAG PRO KUNDE.
>
> Stimmt! Aber nicht den, der zu dem Datum gehört. Oder soll ich das so
> verstehen, daß ich diese Datumsangabe als Where-Cluase beim nächsten
> ("echten") Select nutze?
Vergiß das. Mach es lieber mit dem "min(validFrom)".

>
> >
> > Eine Variante zur Simulation des union ist die, wenn Du die
> beiden Abfragen
> > nacheinander ausführst und die Ergebnisse, d. h. die
> Kundenkennung, in eine
> > temporäte Tabelle schreibst und dann Deine Abrechnung
> laufen läßt. Evtl.
> > besteht auch die Möglichkeit, Deine Tabelle Konditionen
> noch einmal zu
>
> Wie meinst Du das? Nach wäre tatsächlich eine Überarbeitung
> möglich. Es
> sind zwar schon gut 300-Datensätze drin, aber die kann man notfalls ja
> auch noch umschaufeln.
>
> > überarbeiten.
Ich meinte damit, daß die Bedingungen "Minimum von validFrom UND validTo IS
NULL ODER max(zaehler)" nicht gemeinsam benutzt werden sollten. Außerdem ist
in mysql die Konstruktion "select * from tabelle where kenn in (select id
from andere_tabelle where ...." nicht möglich. Du kannst also nur das
Ergebnis der Gruppierung in eine eigene (temporäre) Tabelle (z. B.
"tempKunde") schreiben und dann wie folgt selektieren:
"select kunde, XXXX from tempKunde, <zusätzliche Tabelle> where
	tempKunde.id = <zusätzliche Tabelle>.id (Zusammenhang zwischen  	tempKunde
und der zusätzlichen Tabellen
	:
	:
	:

> > Wie wäre es, die aktuellen Daten UND die
> >Daten des Vormonats
> > in eine eigene Tabelle zu schreiben und am Monatsende während des
>
> Insert into Vormonate (abc, def, ghi, jkl)
>  select abc, def, ghi, jkl
>  from Abrechnungsdaten
>  where Monat = $vormonat
>
Der Vorschlag ist wie folgt:
In der Tabelle mit den aktuellen Daten (aktDat) hälst Du ausschließlich die
Daten des aktuellen und des Vormonats. Es gibt eine weitere Archivtabelle
archDat, in der alle Daten stehen, die älter sind. An jedem Monatsende läßt
Du Deinen Monatsabschluß laufen und lagerst die alten Daten in archDat aus
und löscht die Daten aus aktDat heraus. Die nächtlichen Läufe und alle
Zugriffe am Tage laufen dann wesentlich schneller, da die Datenmenge
wesentlich geringer ist. Je länger ich darüber nachdenke, desto mehr wird
diese Verfahrensweise zu einem MUSS. Deine Anwendung wird auf Grund der
zunehmende Dateigröße automatisch langsamer. Es besteht mit Sicherheit jetzt
noch kein akuter Handlungsbedarf, aber meiner Meinung nach ist das eine
Zeitbombe. Irgendwann wird Dein Kunde sich melden und sich über die langsame
Laufzeit beschweren.
Das Löschen von Datensätzen aus einer Tabelle bewirkt keine (!)
physikalische Verkleinerung der Datei auf der Platte. Meinen Tests nach ist
mysql aber im Gegensatz zun vielen "professionellen" DB-System (z. B.
Informix) trotzdem in der Lage, performant zu arbeiten. Ggf. kann man in
losen Abständen ein "optimize table" laufen lassen. Das verkleinert die
Datei auch physikalisch. So etwas könnte man meiner Meinung nach auch dem
Endanwender als Funktion zur Verfügung stellen.

> Oder gibts's was schnelleres / besseres?
>
> > Abrechnungslaufes die Daten in eine andere Tabelle
> auszulagern? Könnte evtl.
> > auch die Performance im laufenden Monat drastisch erhöhen,
> da Du nur die
> > aktuellen Daten im Zugriff hast.
>
> Das hier klingt auch Klasse.
s. o.

>
> Ab wo wird's denn kritisch? Die Abrechnung läuft nachts
> (Perl) und macht
> folgendes:
> 1. Abfrage auf Abrechnugsdaten
>    a) sum(Wert1) je Kunde
>    b) avg(Wert2) je Kunde
>    c) avg(wert3) je Kunde
> 2. Holen der Kundendaten
> 3. Holen der Konditionen
> 4. Schreiben der Rechnungsdaten in Tabelle
> 5. Versand der Rechnungen per Mail
>
Das "kritisch" läßt sich leider nur im Echtbetrieb ermitteln. Ich denke
aber, daß Du mit der Aufteilung der Daten nie in einen kritischen Bereich
kommen wirst.
Ich hoffe, daß mich andere Mitleser eines Besseren beleeren, wenn meine
Ausführungen bez. der Geschwindigkeit und der Physik falsch sein sollten!!
Danke an die Liste!!

Gruß Alexander

---
*** Weitere Infos zur Mailingliste und MySQL unter http://www.4t2.com/mysql 



php::bar PHP Wiki   -   Listenarchive