Mysql: Aktuelles Datum bei Tabellen mit millionen Einträgen

BugsBastard

Erfahrenes Mitglied
Hallo zusammen,

mein Problem ist eigentlich recht simpel. Ich habe eine Tabelle mit folgendem Schlüssel:
Produkt
Kunde
Datum

Weitere Werte:
Lagerbestand
Abverkauf

Wir erhalten jeden Tag, von manchen Kunden auch nur jede Woche, Abverkaufszahlen. Diese werden allerdings nicht für alle Produkte geliefert, sondern nur für Produkte bei denen auch Lagerbestand existiert bzw. auch Abverkauf vorhanden ist. Um das ganze noch ein bisschen interessanter zu machen, es kann auch sein, daß Daten von einem Tag fehlen, welche erst den nächsten Tag nachgeliefert werden.

Insgesamt reden wir von einem Datenaufkommen von mindestens 100 000 000 Datensätzen in der Db, jeden Tag kommen über 100 000 - 200 000 dazu.

Nun möchte ich den aktuellen Lagerbestand für alle Produkte in allen Geschäften herausfinden. Da ich nicht weiß, wann wir diesen aktuellen Lagerbestand erhalten haben, muß ich 4 Wochen in der Zeit zurückgehen. Meine aktuelle Query wäre demnach:

SELECT kunde, produkt, datum, lagerbestand FROM vertriebsdaten WHERE datum>=DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND datum=(SELECT max(datum) FROM vertriebsdaten as v WHERE v.kunde = kunde AND v.produkt = produkt AND datum>=DATE_SUB(CURDATE(), INTERVAL 30 DAY));

Diese Query ist aber bei der Anzahl der Datensätze (in der Tabelle und in der Rückgabe) sehr langsam. Gibt es bei Mysql noch eine schnellere Variante, bei der man den Maximumwert einer bestimmten Spalte mit den dazugehörigen Werten dieses Datensatzes erhält?

Gruss,

Bugs
 
Bitte den Code formatiert in [code=sql]mein Code[/code] setzen.
So wie er jetzt da steht kann man das Ding kaum lesen


Obs schneller ist oder nicht, kann ich dir nicht direkt sagen. Ich würde aber die Unterabfrage in den FROM-Teil nehmen und die 30-Tag-Rechnung nur einmal ausführen.
Zudem ien Index auf Kunde, Produkt und Datum legen.

SQL:
SELECT
	v_data.kunde, 
	v_data.produkt, 
	v_data.datum, 
	v_data.lagerbestand 	
FROM
	vertriebsdaten AS v_data,
	(	
		SELECT
			v.kunde,
			v.produkt,
			MAX(v.datum) AS max_datum
		FROM
			vertriebsdaten AS v
		WHERE
			v.datum>=DATE_SUB(CURDATE(), INTERVAL 30 DAY))
		GROUP BY
			v.kunde,
			v.produkt
	) AS max_d
WHERE
	max_s.kunde = v_data.kunde
	AND max_s.produkt = v_data.produkt
	AND max_s.max_datum = v_data.datum

Des weiteren zur Performance-Steigerung in MySQL
Performance-Verbesserungen sind keine eindeutige und einfache Sache. Es ist ein testen und heran tasten. Auswerten von Explainplans, SQL umschreiben - ggf. total umschreiben, weiter testen, Anzahl Datensätze der Tabelle vergleichen, ggf. Subqueries machen um die Datenmenge so früh wie möglich klein zu kriegen etc.
Also, so einfach *schnipp*und ein SQL ist schnell - das kannst du vergessen. Diese ganzen Punkte die ich aufgezählt habe gehen auch nicht einfach so mit im Forum hin und her schreiben. Lies dich in das Thema ein. Verscuh es zu verstehen. Und dann setz dich hin und probier dich durch.
 
Zuletzt bearbeitet von einem Moderator:
Hi,

erst mal danke für die Antwort.

Daß ich hier keine Antwort "mach das, dann ist alles jut" bekomme war mir klar :) ich sitz seit mehreren Tagen an dem Problem bzw. dieses Problem kommt immer wieder auf. Daher wollte ich nur mal nachfragen, ob ich einen generellen Denkfehler in der Query habe oder nicht, bzw. ob Mysql für so etwas Funktionen bietet, welche das beschleunigen können oder ob jemand eine andere Herangehensweise hätte. Ich möchte hier keinen fertigen Code gepostet haben sondern bräuchte einfach ein paar Ideen (wobei, wenn jemand mir eine SQL komplett fertig machen wil sträube ich mich natürlich nicht :)).

Gruss,

Bugs (Thomas)
 
Zurück