Zum Inhalt springen

Doppeltes group by


python

Empfohlene Beiträge

Hi,

ich hab einen Datenbank in der Logeinträge mit den folgenden Feldern gespeichert werden:

ID|Seriennummer|Artikelnummer|Zeit

Jetzt brauche ich alle Artikelnummern der letzten Einträge aller Seriennummer.

Ich will also zuerst nach Seriennummern welche nach Zeit sortiert sind gruppieren und das Ergebniss soll dann nach Artikelnummern gruppiert werden und nach Artikelnummern sortiert werden.

Bisher habe ich es mit folgendem subselect gelöst:

select Artikelnummer from (select Artikelnummer, Zeit from Log group by Seriennummer order by Zeit) group by Artikelnummer order by Artikelnummer;

Da ich aber über 100000 Einträge hab und es bald 1 Mio werden, dauert dieses Select jetzt schon über 5 Sekunden, was für meine Webapplikation zu lange ist.

Weiß jemand noch eine andere Möglichkeit, wie ich das schneller lösen kann?

mfg Stefan

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

ich gehe davon aus, dass Deine Felder entsprechend indiziert sind. Mache kein Subselect, sondern einen entsprechenden Join. Falls dies dann immer noch zu langsam sein sollte, kannst Du ggf. über Views oder Läufe, die die Daten vorbereiten, noch einmal optimieren.

Es wäre generell sinnvoll, Du würdest das DBMS dazu nennen, sowie die Struktur der Tabellen und der genannten Sprache in der Du arbeitest, ggf. mit Code Auszügen

HTH Phil

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

erstmal danke für deine antwort!

wie machen ich den einen Join, wenn ich nur Daten von einer Tabelle abfragen will?

Als DBMS verwende ich MySQL und als Programmiersprache Python.

Ich habe es jetzt mit einer Temporären Tabelle gelöst, die einmal am Tag erstellt wird, da die Daten auch nur einmal am Tag geupdatet werden, in der die Einträge schon nach Seriennummern vorgruppiert sind.

Diese Lösung finden ich aber eigentlich ziemlich unsauber.

mfg Stefan

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

Du definierst eben die Tabelle 2 mal über einen Alias und dann joinst Du.

Ich hoffe, Du machst kein "Create Temp Table", denn diese Tabellen bleiben nur so lange erhalten, wie die Sitzung aktiv ist.

Einfach mal mit dem Join + Index probieren, sonst bitte auch mal den Pythoncode posten.

HTH

Phil

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

also ich hab da mal ein paar Fragen die Sinnhaftigkeit betreffend. Das ist meistens der beste Weg ein SQL zu beschleunigen :D

1. Wenn Du ein GROUP BY verwendest, müssen alle Spalten, die nicht in einer Aggregatsfunktion "verpackt" sind ebenfalls ins GROUP BY. Es ist eine Eigenheit von mysql, die GROUP BY Klausel stillschweigend zu erweitern (ich glaub ab V5 wird hier auch endlich ein Fehler geworfen).

Dein Subselect sieht, nachdem es mysql "verbessert" hat, also so aus:

select [b]seriennummer[/b],Artikelnummer, Zeit from Log group by Seriennummer,[b]artikelnummer,zeit[/b] order by Zeit
Was aber macht ein GROUP BY das alle Spalten des SQLs beinhaltet? Es dampft doppelte Datensätze ein. Da wird nichts mehr gruppiert. Wonach auch. Sollte mysql hier ein anderes Ergebnis liefern, so ist das ein riesen Bug! In MSSQL, Postgres,DB2 oder Oracle wäre dieses SQL nicht mal lauffähig. Du erhältst das gleiche Resultat wenn Du ein
SELECT DISTINCT seriennummer,Artikelnummer, Zeit FROM ...
verwendest. 2. Du verwendest ein ORDER BY im Subselect? Warum? Ein ORDER BY wird benutzt um die Ausgabe zu sortieren. In einem Subselekt hat es nichts verloren. Evtl bemerkt mysql das und ignoriert den ORDER BY andernfalls sortierst Du einmal den distincten Datenbestand deiner Tabelle - und zwar komplett umsonst. Du hättest im schlimmsten Fall also schon 2 Sorts allein im Subselect!! 3. Du verwendest keine WHERE Einschränkung. Bedeutet, die Laufzeit deiner Abfrage ist mindestens direkt proportional zur Anzahl der in der Tabelle enthaltenen Datensätze. Dein Rechner hat also 10mal soviel zu tun wenn 10mal soviele Daten vorhanden sind. Wenn irgendwann der Arbeitsspeicher knapp wird, müssen Teile auf die Platte ausgelagert werden, was die Abarbeitung zusätzlich verlangsamen wird. Für eine Webanwendung gänzlich ungeeignet. Entweder du baust eine WHERE Bedingung ein oder Du verwendest das LIMIT Schlüsselwort und beschränkst die Ausgabe somit. Kein User interessiert sich für eine Treffermenge die zig tausend Ergebnisse bringt. Oder hast Du schon mal in einer Google Suche alle Seiten durchgeklickt? Falls Du solche Komplettauswertungen machen möchtest, dann ist das eher eine Datawarehouseanwendung aber keine Webseite die nach spätestens 2 Sekunden ein Ergebnis bringen muss. Kürzt man dein SQL auf das wesentliche zusammen, dann sieht das so aus:
SELECT DISTINCT artikelnummer ORDER BY artikelnummer

Bevor du irgendwelche Workarounds einbaust, würd ich erstmal über die obigen 3 Punkte nachdenken ansonsten kommst auf keinen grünen Zweig.

Dim

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

ich möchte auf das "Datawarehouse" eingehen. Vielleicht ist es ja Sinn und Zweck die Daten aus einem Datawarehouse auszuwerten. Dann würde aber der Fehler in Deinem Konzept liegen, denn eine Auswertung folgt nicht aus dem Echtdatenbestand, sondern im Datawarehouse, wo Die Daten entsprechend vor verarbeitet werden. Der Ansatz mit den mehreren Tabellen wäre dies. Falls ich mit der Idee, dass Du hier ein Datawarehouse konstruieren willst richtig liege, würde ich Dir dazu raten, Dir die Daten in eine eigene Datenbank zu kopieren (z.B. weitere Datenbank auf dem Server). Dann innerhalb der Datenbank mit Hilfe von Stored Procedures und verschiedenen zeitgesteuerten Läufen die Daten entsprechend vor zu verarbeiten. Dem Benutzer würde ich dann auf die Tabellen nur ein Leserecht einräumen. Als Report kannst Du zwar weiterhin auf eine Webanwendung setzen, ich würde Dir aber zu einem entsprechenden Tool raten z.B. Crystal Reports oder auch PDF mit Hilfe von XML:Fo erzeugst und als fertige Dateien bereit stellst. CR hat den Vorteil, dass der Benutzer sich selbst das Layout erstellen kann

HTH Phil

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...