SELECT FROM * Auswahl
Moderator: Moderatoren
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2518
- Registriert: Mi, 28. Jul 2010 17:16
- Hat sich bedankt: 12 Mal
- Danksagung erhalten: 77 Mal
SELECT FROM * Auswahl
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.
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
Gruss Carlo
- nightcrawler
- 1000 working lines a day
- Beiträge: 653
- Registriert: Di, 24. Apr 2012 16:33
- Wohnort: 72184 Weitingen
- Hat sich bedankt: 3 Mal
- Danksagung erhalten: 96 Mal
- Kontaktdaten:
- Marcus Herz
- 1000 working lines a day
- Beiträge: 860
- Registriert: Mo, 16. Jan 2006 8:13
- Wohnort: Allgäu
- Hat sich bedankt: 39 Mal
- Danksagung erhalten: 196 Mal
- Kontaktdaten:
Re: SELECT FROM * Auswahl
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 ))
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
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
- brandelh
- Foren-Moderator
- Beiträge: 15699
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 69 Mal
- Danksagung erhalten: 34 Mal
- Kontaktdaten:
Re: SELECT FROM * Auswahl
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
Hubert
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9387
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 103 Mal
- Danksagung erhalten: 362 Mal
- Kontaktdaten:
Re: SELECT FROM * Auswahl
Das ist für SQL-Rookies ein wichtiger Hinweis, Hubert, aber bei Carlo bist Du damit, glaube ich, an der eher falschen Adresse.
Herzlich,
Tom
Tom
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2829
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 97 Mal
- Danksagung erhalten: 13 Mal
Re: SELECT FROM * Auswahl
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.
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.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9387
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 103 Mal
- Danksagung erhalten: 362 Mal
- Kontaktdaten:
Re: SELECT FROM * Auswahl
Könnte man nicht irgendwie mit einem Autoincrement herumeiern, dessen Wert mit dem der Timestamp verbunden wird?
Herzlich,
Tom
Tom
- Marcus Herz
- 1000 working lines a day
- Beiträge: 860
- Registriert: Mo, 16. Jan 2006 8:13
- Wohnort: Allgäu
- Hat sich bedankt: 39 Mal
- Danksagung erhalten: 196 Mal
- Kontaktdaten:
Re: SELECT FROM * Auswahl
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 ...)
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
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2518
- Registriert: Mi, 28. Jul 2010 17:16
- Hat sich bedankt: 12 Mal
- Danksagung erhalten: 77 Mal
Re: SELECT FROM * Auswahl
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"
Muss vermutlich noch optimiert werden.
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"
Muss vermutlich noch optimiert werden.
Valar Morghulis
Gruss Carlo
Gruss Carlo
- Marcus Herz
- 1000 working lines a day
- Beiträge: 860
- Registriert: Mo, 16. Jan 2006 8:13
- Wohnort: Allgäu
- Hat sich bedankt: 39 Mal
- Danksagung erhalten: 196 Mal
- Kontaktdaten:
Re: SELECT FROM * Auswahl
versuch mal einen index auf unixtimestamp
Gruß Marcus
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
- Marcus Herz
- 1000 working lines a day
- Beiträge: 860
- Registriert: Mo, 16. Jan 2006 8:13
- Wohnort: Allgäu
- Hat sich bedankt: 39 Mal
- Danksagung erhalten: 196 Mal
- Kontaktdaten:
Re: SELECT FROM * Auswahl
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 ... )
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
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2518
- Registriert: Mi, 28. Jul 2010 17:16
- Hat sich bedankt: 12 Mal
- Danksagung erhalten: 77 Mal
Re: SELECT FROM * Auswahl
Hallo Marcus
Danke für den Tip.
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.
Das waren jetzt die Experimete unter PGAdmin.
Jetzt kommt die Umsetzung im Programm.
Danke für den Tip.
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;
Jetzt kommt die Umsetzung im Programm.
Valar Morghulis
Gruss Carlo
Gruss Carlo
- Marcus Herz
- 1000 working lines a day
- Beiträge: 860
- Registriert: Mo, 16. Jan 2006 8:13
- Wohnort: Allgäu
- Hat sich bedankt: 39 Mal
- Danksagung erhalten: 196 Mal
- Kontaktdaten:
Re: SELECT FROM * Auswahl
100 Mio Datensätze, das lob ich mir, und es funktioniert. Ist das nicht schön!
Gruß Marcus
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
Den Kopf in den Sand zu stecken verbessert die Welt auch nicht.
- AUGE_OHR
- Marvin
- Beiträge: 12911
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: SELECT FROM * Auswahl
hi,
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"
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 , 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.
ich habe keine 100 Million Datensätze zu Hand um es zu probieren.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.
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"
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 , 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
Jimmy
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2518
- Registriert: Mi, 28. Jul 2010 17:16
- Hat sich bedankt: 12 Mal
- Danksagung erhalten: 77 Mal
Re: SELECT FROM * Auswahl
@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.
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
Gruss Carlo