AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Otimierung SQL Abfrage oder Logik
Thema durchsuchen
Ansicht
Themen-Optionen

Otimierung SQL Abfrage oder Logik

Ein Thema von haentschman · begonnen am 11. Dez 2015 · letzter Beitrag vom 13. Dez 2015
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von haentschman
haentschman
Online

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.388 Beiträge
 
Delphi 12 Athens
 
#1

Otimierung SQL Abfrage oder Logik

  Alt 11. Dez 2015, 19:13
Datenbank: Firebird • Version: 2.5 • Zugriff über: IBDAC
Hallöle...

Ich bräuchte mal ein paar Tipps zur Optimierung. Außerdem redet ja sonst keiner mit mir...

Gegeben:
* Datentabelle mit 3,5 Mio Datensätzen
* In der Datentabelle sind nur die Werte gespeichert wenn sie sich ändern. Bsp. Value 5,6,7,5,4 - Value 5,5,6,6,6,6,7,7,5,5,4 gibts nicht.
* Gewählter Zeitraum für die SQL Abfrage zum Beispiel letzte 24 Stunden.
* Es gibt 2 Modi: Anzeige der Daten im kompletten Zeitraum (Bild1) bzw. nur die vorhandenen Daten (Bild 2)
* Es kann vorkommen das die vorhandenen Daten nicht den gesamten Zeitraum abdecken. Das passiert z.B. wenn das Gerät ausgeschaltet war und keine Daten aufgezeichnet hat. Dazu generiere ich mir in der Komplettansicht für jede Serie einen Anfangs und Endwert der aus dem vorhergehenden vorhandenen Datensatz besteht. Darin besteht der Flaschenhals.

* Ein Thread holt die Daten für jede Serie nacheinander ab und füllt damit für jede Serie getrennte Liste. (incl. evt. generiertem Anfang und Ende)
In diesem Beispiel würde die Abfrage auf den vorhergehenden Wert 12 Mal durchgeführt werden. Ob "Kerndaten" vorhanden sind oder nicht. Jede dieser Abfragen benötigt im Durchschnitt 70ms. Da bedeutet das incl. Transport (100ms rechnet sich besser ) 1,2 Sekunden nur für die "Berechnung" flöten gehen. Dass gefällt mir nicht wirklich...

Soll:
* Ideen für Optimierung ohne Komplettumbau... Letztendlich komme ich wahrscheinlich nicht um eine SQL Abfrage herum weil ich mir die Ergebnisse nicht anderweitig "Merken" kann. Über eine SP, die mir die Values listet, denke ich schon nach. Die muß aber die Werte auch aus der DB generieren...

SQL:
Beide Abfragen bringen die korrekten Ergebnisse. Der komplette Join (wäre schön) liegt nur 10ms drüber.

komplett mit Join
Code:
select first (1) D.F_PARAMETER_ID, D.F_TIMESTAMP_UNIX, D.F_POWER_STATE, D.F_VALUE, T.F_TYPE_ID from T_RECORD_DATA D
join T_DEVICE_PARAMETERS P on P.ID = D.F_PARAMETER_ID
join T_MEASURE_TYPES T on T.ID = P.F_MEASURE_TYPE_ID
where D.F_PARAMETER_ID = 1060 and D.F_TIMESTAMP_UNIX < 1449737313
order by F_TIMESTAMP_UNIX desc
vereinfacht
Code:
select first (1) F_TIMESTAMP_UNIX, F_VALUE from T_RECORD_DATA D
where F_PARAMETER_ID = 1060 and F_TIMESTAMP_UNIX < 1449737313
order by F_TIMESTAMP_UNIX desc
Miniaturansicht angehängter Grafiken
bild1.png   bild2.png  

Geändert von haentschman (11. Dez 2015 um 19:22 Uhr)
  Mit Zitat antworten Zitat
HeZa

Registriert seit: 4. Nov 2004
Ort: Dortmund
182 Beiträge
 
Delphi 10 Seattle Professional
 
#2

AW: Otimierung SQL Abfrage oder Logik

  Alt 11. Dez 2015, 19:27
Ich werde daraus nicht ganz schlau. ?-)

Das FIRST (1) läßt mich schaudern, ließt du jeden Datenpunkt deines Diagramms einzelnd? Das wäre Fatal.
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman
Online

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.388 Beiträge
 
Delphi 12 Athens
 
#3

AW: Otimierung SQL Abfrage oder Logik

  Alt 11. Dez 2015, 19:30
Danke...

Prinzipiell geht es um die gerade horizontale Linie die du im Chart rechts siehst. Der Chart kann die nur zeichnen bzw. die X-Achse breit ziehen wenn der letzte "Datumswert" den Wert des letzten vorhergehenden Wertes hat.
Die Abfrage dient nur dazu EINEN und zwar den letzten vor einem bestimmten Timestamp abzufragen. Deshalb First(1) und desc... Das gruslige daran ist das der Server immer erst alle Daten vor dem Zeitpunkt lesen muß um den EINEN zurückzugeben. Das geht durch den desc Index trotzdem erstaunlich schnell. Mich stört das ich in der Summe der Abfragen Zeit einbüße...
Zitat:
ließt du jeden Datenpunkt deines Diagramms einzelnd?
...Das wäre allerdings Selbstmo... Wenn der User, auch wenn es bescheuert ist, sich alle Daten darstellen will kommen in diesem Beispiel pro Serie rund 60000 also 360000 Werte zusammen. Das ganze dauert mit Darstellung 12 Sekunden. Selbst das wäre akzeptabel. Gerade bei den "wenig" Daten stört mich der Overhead der "Berechnung" der vorhergehenden Werte.

Nachtrag: Tsss... den letzten habe ich mir auch ausgelesen. Dabei entspricht das genau dem letzten Datensatz der "Kerndaten". Den habe ich ja schon. Ich muß nur einen holen wenn gar keine "Kerndaten" vorhanden sind. Am Anfang komme ich aber nicht drum herum...

Da hab ich doch eine Idee. Um die gerade Linie auf die "0" Linie zu ziehen bräuchte ich ja jeweils einen Datenpunkt des Anfanges und der ersten Daten (Equivalent am Ende) zu füttern. Das würde die Werteabfrage per SQL obsolet machen. Dann wären halt keine Linien in der "Mitte"...
Miniaturansicht angehängter Grafiken
bild3.png  

Geändert von haentschman (11. Dez 2015 um 19:56 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman
Online

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.388 Beiträge
 
Delphi 12 Athens
 
#4

AW: Otimierung SQL Abfrage oder Logik

  Alt 12. Dez 2015, 08:28
Moin...

Na bitte geht doch. Ich habe jetzt jeweils den ersten bzw. letzten Datensatz der "Kerndaten" für Beginn und Ende benutzt. Das erspart die SQL Abfragen. Nur im Extremfalle wenn keine Kerndaten vorhanden sind wird Anfang und Ende aus der DB geholt...

Schön das wir drüber geredet haben...
Miniaturansicht angehängter Grafiken
bild1.png   bild2.png  

Geändert von haentschman (12. Dez 2015 um 09:32 Uhr)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#5

AW: Otimierung SQL Abfrage oder Logik

  Alt 12. Dez 2015, 09:48
Ich habe zwar nicht genau verstanden, was Du willst, aber ich denke, Du hast einzelne Abschnitte und willst die irgendwie erkennen.

Datenbanken sollten imho immer so aufgebaut werden, das die Kernfunktionen und -abfragen performant umgesetzt werden sollten. Hier ist eine Kernabfrage die Sache mit den Abschnitten (wenn ich das richtig verstanden habe).

Du solltest eine Tabelle mit den expliziten Abschnitten pflegen. Dann geht die Abfrage viel schneller. Diese Tabelle könnte immer dann geupdated (oder upgedatet?) werden, wenn ein neuer Abschnitt beginnt (beim Ausschalten ist das ja ein wenig spät ). Beim Einschalten sucht man sich einmalig das Ende des letzten Abschnittes, trägt es in die Tabelle ein und danach den Anfang (nämlich 'jetzt') das neuen Abschnittes. So hast Du deine 70ms verteilt (nämlich bei der Datenerfassung).

Oder habe ich das Problem komplett falsch verstanden?
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman
Online

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.388 Beiträge
 
Delphi 12 Athens
 
#6

AW: Otimierung SQL Abfrage oder Logik

  Alt 12. Dez 2015, 10:38
Danke für deine Anteilnahme...
Zitat:
Oder habe ich das Problem komplett falsch verstanden?
Ja leider...aber nicht schlimm. Den Erklärbär hab ich schon wegen Hilfe kontaktiert...

Das Problem ist nicht die Datenbank sondern die Anzeige bei Anzeigezeitraum größer als Datenzeitraum der vorhandenen Daten. Um diese waagerechten Striche der Serien (Anfang und Ende) zu bekommen benötigt man einen Datenpunkt am Anfang Anzeigezeitraum und Ende Anzeigezeitraum. Diese Werte hatte ich aus der DB ermittelt. Auch wenn die einzelne Anweisung schnell war brachte die Summe der Abfragen einen blöden Overhead. Das habe ich jetzt so gelöst, das ich schon geladene Daten verwende als immer die Werte neu zu ermitteln.
  Mit Zitat antworten Zitat
HeZa

Registriert seit: 4. Nov 2004
Ort: Dortmund
182 Beiträge
 
Delphi 10 Seattle Professional
 
#7

AW: Otimierung SQL Abfrage oder Logik

  Alt 13. Dez 2015, 14:42
Das Problem ist nicht die Datenbank sondern die Anzeige bei Anzeigezeitraum größer als Datenzeitraum der vorhandenen Daten. Um diese waagerechten Striche der Serien (Anfang und Ende) zu bekommen benötigt man einen Datenpunkt am Anfang Anzeigezeitraum und Ende Anzeigezeitraum. Diese Werte hatte ich aus der DB ermittelt. Auch wenn die einzelne Anweisung schnell war brachte die Summe der Abfragen einen blöden Overhead.
Das Problem ist (oder war) also die Skalierung der Anzeige?

Was ich immer noch nicht verstehe, wieso kommst du nicht mit einem einzigen SELECT-Statement aus:
Code:
select
  D.F_PARAMETER_ID, D.F_TIMESTAMP_UNIX, D.F_POWER_STATE, D.F_VALUE, T.F_TYPE_ID
from
  T_RECORD_DATA D
  join T_DEVICE_PARAMETERS P on P.ID = D.F_PARAMETER_ID
  join T_MEASURE_TYPES T on T.ID = P.F_MEASURE_TYPE_ID
where
  D.F_PARAMETER_ID = 1060 and D.F_TIMESTAMP_UNIX between <startzeitpunkt> and <endzeitpunkt>
order by
  F_TIMESTAMP_UNIX desc
<startzeitpunkt> und <endzeitpunkt> würden in diesem Fall dadurch bestimmt werden, welchen Zeitraum du anzeigen möchtest.

Ich weiß jetzt nicht, ob sich das Thema für dich erledigt hat, ansonsten hätte ich noch ein paar Fragen:
  • Zeichnest du das Diagram selbst?
  • Wann bzw. warum kommt es zu einer senkrechten gestrichelten Linie?
  • Bedeuten die farbigen waagerechten Linien, das der Wert gleich geblieben ist, oder das keine Messung erfolgte?
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman
Online

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.388 Beiträge
 
Delphi 12 Athens
 
#8

AW: Otimierung SQL Abfrage oder Logik

  Alt 13. Dez 2015, 15:11
Danke für deine Zeit...
Zitat:
Ich weiß jetzt nicht, ob sich das Thema für dich erledigt hat, ansonsten hätte ich noch ein paar Fragen:
...prinzipiell ja. Aber ich beantworte dir das gern.
Zitat:
Was ich immer noch nicht verstehe, wieso kommst du nicht mit einem einzigen SELECT-Statement aus:
Für das Laden der Daten des Zeitraumes ist ein select Statement zuständig.
Zitat:
Zeichnest du das Diagram selbst?
Nein. TChart.
Zitat:
Bedeuten die farbigen waagerechten Linien, das der Wert gleich geblieben ist, oder das keine Messung erfolgte?
Die waagerechte Linie bedeutet (soll bedeuten) das keine Werte gemessen wurden. Quasi wie auf dem EKG... piiieeeep:
Zitat:
Wann bzw. warum kommt es zu einer senkrechten gestrichelten Linie?
Die berechnet TChart aus den vorliegen Daten anhand einiger "Vorgaben". Das läßt man in der Regel auf Automatik, sonst kommen manchmal komische Bilder raus.

Nochmal ein Beispiel:
* Chart soll angezeigt werden vom 1. bis 31.
Ein select Statement lädt die Daten vom 1. bis 31. (Daten vorhanden: 11.,12.,13.)
Jetzt würde TChart eine Grafik skalieren vom 11. - 13. Das ist ein Modus den ich dem Nutzer zur Verfügung stelle.
Der 2. "Modus" soll den gesamten Zeitraum (1. - 31.) auf der X-Achse darstellen und die Daten (11.,12.,13.) in der Mitte. Um die waagerechte Linie darzustellen benötigt TChart einen Wert für den 1. und einen Wert für den 31. Diese habe ich mir per seperate SQL geholt. Das machte dann 3 SQL Anfragen per Serie. Die 2 zusätzlichen brachten den zeitlichen Overhead der mir nicht gefiel. Das war die eigentliche Frage...
Die 2 zusätzlichen SQL Anfragen habe ich jetzt gespart und die Werte für den 1. und 31. aus den vorhandenen Daten generiert. Nur wenn keine Daten geladen wurden muß ich nun 1x den letzten Wert vor dem gewählen Zeitraum holen um eine Linie darzustellen.
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#9

AW: Otimierung SQL Abfrage oder Logik

  Alt 13. Dez 2015, 15:15
  • Wann bzw. warum kommt es zu einer senkrechten gestrichelten Linie?
  • Bedeuten die farbigen waagerechten Linien, das der Wert gleich geblieben ist, oder das keine Messung erfolgte?
Das ist ein Problem an der Sache. Auch wenn es nicht so schön aussieht, sollte man fehlende Daten nicht zeichnen oder zumindest anders kenntlich machen (Strichellinie/graue Linie).

Dein anfängliches Problem kann ich nachvollziehen: Ich möchte vielleicht den letzten Wert der letzten Messserie (z.B. am Tag davor) als Referenz haben um zu gucken, wie sich der erste Wert davon unterscheidet. Da liegt vielleicht ein Ansatz zum Optimieren: wenn der letzte Wert zu lange her ist, interessiert der mich vielleicht auch gar nicht mehr.

Aber sich einfach einen Wert auszusuchen um Lücken zu füllen ist vielleicht nicht die beste Idee.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#10

AW: Otimierung SQL Abfrage oder Logik

  Alt 13. Dez 2015, 15:20
Ich hab es so verstanden, dass er einen fixen Zeitraum anzeigen will, in der Gradikkomponente (automatisch) definiert über minimale und maximale Werte im Zeitstrahl. Normalerweise erhält er diese Werte auch, mittels einer Abfrage wie Deiner, weil kleinschrittige Messwerte vorliegen.
Bei Anlagenausfall fehlen ab Messwerte für größere Zeiträume, was zu häßlichen "Kurven" führt.
Er braucht also für die Diagramme notfalls Fakewerte, die garantiert Anfang und Ende setzen, also Wertepaare Startzeitpunkt;0, Endzeitpunkt;0, sowie ZeitpunktErsterVorhandeneMeßwert-Schrittweite;0, ZeitpunktLetzterVorhandenerMeßwert+Schrittweite;0
um mit angemessener Flanke vom Nullpunkt einzusteigen.

Ich verstehe eher nicht, warum er die Werte nicht einfach manuell ergänzt. Zumindest klingt die Beschreibung nicht so, als ob die Chartkomponente direkt die SQL Werte schluckt, sondern aus einer Werteliste gefüttert wird, die einfach zu manipulieren wäre.

rote Schranke: Hab jetzt die Antworten noch nicht gelesen
Gruß, Jo
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz