SELECT FROM * Auswahl

Alles zum SQL-Dialekt

Moderator: Moderatoren

Antworten
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

SELECT FROM * Auswahl

Beitrag von ramses »

Guten Morgen

ich stehe heute ein wenig auf dem Schlauch....evtl weiss jemand weiter.

Ich habe eine sehr grosse Datenbank mit Messwerten. Aus dieser möchte ich 4000 Datensätze ab einem bestimmten Datum als Ergebniss haben.
Die Datenbank hat ein Feld Datum, Zeit sowie ein Feld mit einem Unix Timestamp.
(Unix Timestamp = vergangene ms seit 01.01.1970 für heute 7:00 ist dies z.B. 1578981600000 )

Wie stelle ich das Select Query für ein Ergebniss mit 4000 Sätzen zusammen das mit ein Datensatz ab einer bestimmten Uhrzeit beginnt JEDOCH zwischen zwei Datensätzen im Ergebniss der Unix Timestamp immer MINDESTENS z.B. 60000 auseinanderliegt. (60000 = 1 Minute )
Also alle dazwischenliegenden Datensätze übergeht / ausblendet.

Bis jetzt habe ich einfach solange jeweils 1000 Sätze gelesen und das Ergebniss Set im Programm selbst ausgewertet und zusammengestellt.

Da ich nun ein Ergebnis Set von 4000 Sätzen für einen viel längeren Zeitraum benötige ist dauert diese Art der Auswahl viel zu lange.
Die Auswahl von z.B. 60000 ist nicht fix sondern kann auch andere Werte haben.
Valar Morghulis

Gruss Carlo
Benutzeravatar
nightcrawler
1000 working lines a day
1000 working lines a day
Beiträge: 650
Registriert: Di, 24. Apr 2012 16:33
Wohnort: 72184 Weitingen
Hat sich bedankt: 3 Mal
Danksagung erhalten: 96 Mal
Kontaktdaten:

Re: SELECT FROM * Auswahl

Beitrag von nightcrawler »

geht m.E. nicht in einer Query, da diese nicht sequentiell arbeiten.
--
Joachim
Joachim Dürr Softwareengineering
https://www.jd-engineering.de
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: SELECT FROM * Auswahl

Beitrag von Marcus Herz »

Eine Möglichkeit, aber nur eine Annäherung ist ein group by

select min(timestamp)
group by int(timestamp / 60000 )

so in etwa bekommst du für jedes intervall einen Satz, die müssen aber nicht zwangsläufig 60000 auseinanderliegen, aber einen je 60000.
Mit diesem kannst du dann
select * from table where timestamp in (
select min(timestamp)
group by int(timestamp / 60000 ))
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: SELECT FROM * Auswahl

Beitrag von brandelh »

das * für alle Felder sollte zumindest mal auf die nötigen begrenzt werden, je nach Anzahl und Typ der Felder macht das viel aus
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: SELECT FROM * Auswahl

Beitrag von Tom »

Das ist für SQL-Rookies ein wichtiger Hinweis, Hubert, aber bei Carlo bist Du damit, glaube ich, an der eher falschen Adresse. :wink:
Herzlich,
Tom
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: SELECT FROM * Auswahl

Beitrag von georg »

Hallo,


das geht schon. Z.B. nimmt man einen Ergebniswert auf, der als TIMESTAMP/6000 definiert ist, und setzt diesen Wert auf DISTINCT, so dass ein sekundengenauer Timestamp nur einmal in das Ergebnis gerät. Ob man mit Timestamp aktuell rechnen kann, das kann ich nicht sagen, aber es gibt ja genug Konversionsfunktionen, um ein solches Ziel zu erreichen.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: SELECT FROM * Auswahl

Beitrag von Tom »

Könnte man nicht irgendwie mit einem Autoincrement herumeiern, dessen Wert mit dem der Timestamp verbunden wird?
Herzlich,
Tom
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: SELECT FROM * Auswahl

Beitrag von Marcus Herz »

select *
kommt auf die Datenbank an
Bei ADS ist ein select * bei einem live Cursor schneller, weil dann keinen Kopie erzeugt werden muss.

Distint und Group by auf einem Ausdruck ergibt das gleiche Ergebnis, was performnater ist, muss man testen. Glaub nicht dass da ein Unterschied besteht

Wenns einen primary key gibt, klar, war nur aus der Vorgabe nicht ersichtlich:
select * from table
where primarykey in (
select min(primarykey)
group by ...)
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: SELECT FROM * Auswahl

Beitrag von ramses »

Danke für eure Tips.

Ich versuche eigentlich grundsätzlich immer select * zu vermeiden und immer die geforderten Felder und Reihenfolge anzugeben ......

Folgendes Query hat jetzt mal in 450ms zu einem brauchbaren Ergebnis geführt:
Die Tabelle hat einen Index auf dem Feld "datums"
pg_group.jpg
pg_group.jpg (75.88 KiB) 9287 mal betrachtet
Muss vermutlich noch optimiert werden.
Valar Morghulis

Gruss Carlo
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: SELECT FROM * Auswahl

Beitrag von Marcus Herz »

versuch mal einen index auf unixtimestamp
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: SELECT FROM * Auswahl

Beitrag von ramses »

Dann sind die Ausführungs Zeiten 50-100 ms höher also schlechter.
Valar Morghulis

Gruss Carlo
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: SELECT FROM * Auswahl

Beitrag von Marcus Herz »

interessant.
Wahrscheinlich weil die Sätze ja sequentiell geschrieben und nie wieder verändert werden.
Das Subselect kannst du noch optimieren:
select * from table
where <bedingung>
and unixtimestamp in (
select unixtimestamp from table
where <bedingung>
group by ... )
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: SELECT FROM * Auswahl

Beitrag von ramses »

Hallo Marcus

Danke für den Tip.
Marcus Herz hat geschrieben: Di, 14. Jan 2020 16:24 Das Subselect kannst du noch optimieren
Nein, nicht kannst! Es ist sogar ein absolutes muss.
In der vollständigen Datenbank die ca. 100 Mio Datensätze enthält dauert die Ausführungszeit ohne der vorgeschlagene Optimierung ca. 3 Minuten.
Für Datensätze die etwa in der mitte des Datenbestands liegen. Mit der Optimierung im SubSelect dann perfekte 300-337 ms.

Code: Alles auswählen

select unixstamp,datums,zeit,data from plantA 
  where datums >= '20150808' and datums <= '20150815' and unixstamp in (
     select min(unixstamp) from plantA where datums >= '20150508' and datums <= '20150815'
      group by floor(unixstamp / 120000 )) 
  order by unixstamp limit 4000;
Das waren jetzt die Experimete unter PGAdmin.
Jetzt kommt die Umsetzung im Programm.
Valar Morghulis

Gruss Carlo
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: SELECT FROM * Auswahl

Beitrag von Marcus Herz »

100 Mio Datensätze, das lob ich mir, und es funktioniert. Ist das nicht schön!
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: SELECT FROM * Auswahl

Beitrag von AUGE_OHR »

hi,
ramses hat geschrieben: Di, 14. Jan 2020 21:36 In der vollständigen Datenbank die ca. 100 Mio Datensätze enthält dauert die Ausführungszeit ohne der vorgeschlagene Optimierung ca. 3 Minuten.
Für Datensätze die etwa in der mitte des Datenbestands liegen. Mit der Optimierung im SubSelect dann perfekte 300-337 ms.
ich habe keine 100 Million Datensätze zu Hand um es zu probieren. :-"

Frage : die Zeit-Abstände der einzelnen ROW sind die Konstant :?:

wenn ich solche Messdaten habe kommen die ja in definierten Abständen und dann heisst es : "think SQL" :idea:
ich würde es dann mit PostgreSQL Function "im" Select versuchen wobei ich mir ein Progressbar als Vorlage vorstelle.

für so was verwende ich MOD() Modulo was es unter PostgreSQL auch gibt.
die Position erhält du durch die PostgreSQL Function Row_Number()

du gehst also nicht nach der Time Stamp [-X , nachdem du Anfang-Ende hast, sondern einfach nach "Schrittweite" wenn der Time Stamp Konstant und sortiert ist.
die "Schrittweite" ist ja der 2nd Parameter der für MOD() benötigt wird und den kannst du beliebig Skalieren.
gruss by OHR
Jimmy
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: SELECT FROM * Auswahl

Beitrag von ramses »

@Marcus

Ja, es ist wirklich schön! Beinahe zu schön.

@Jimmy

Die Zeitabstände sind konstant aber nicht immer mit dem gleichen Intervall. Möglich sind unterschiedliche Werte zwischen 1-5 Sekunden je nachdem was gerade Abläuft. Das mit der Schrittweite mit der Record Nummer hat auch früher mit DBF Dateien nie wirklich funktioniert.

Obige Lösung bringt jetzt genau die gewünschten Daten.
group by floor(unixstamp / 120000 )
Sorgt hier dafür dass Zwischen 2 Sätzen mindestens 120 Sekunden liegen. Mit dem UnixTimeStamp gerechnet.
Und dann können natürlich ab und zu auch einzelne Datensätze fehlen, z.B. während Softwareanpassungen, Updates oder Updates des WindowsServers usw. weil die Datenerfassung 24/7 läuft.
Valar Morghulis

Gruss Carlo
Antworten