| Autor |
Beitrag |
Hans-Georg
      
Beiträge: 23
|
Verfasst: Di 28.09.10 10:07
Hallo
Ich suche mit SQL (Select) in einer Datenbank
da diese sehr groß ist möchte ich eine Fortschrittsanzeige
einbauen da der User meint das öfters nichts passiert geht
das auch bei SQL wenn ja wie
Danke im voraus
Hans-Georg
|
|
Nersgatt
      
Beiträge: 1581
Erhaltene Danke: 279
Delphi 10 Seattle Prof.
|
Verfasst: Di 28.09.10 10:09
Wenn Du die Datensätze nicht manuell sequenziell durchsuchst, wird das nicht gehen.
Meiner Erfahrung nach kann man langsame Datenbankabfragen meistens um den Faktor 10 (mindestens) beschleunigen, wenn man Designfehler behebt, Indizies richtig setzt und sauber programmiert.
_________________ Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
|
|
Sinspin
      
Beiträge: 1336
Erhaltene Danke: 119
Win 10
RIO, CE, Lazarus
|
Verfasst: Di 28.09.10 10:28
Das ist abhängig von der verwendeten Datenbank aber es geht. Wir verwenden hier in der Firma ADS, da gibt es entsprechende Callbackroutinen mit denen man eine Fortschrittsanzeige während langen SQL Statements anzeigen kann. Damit sind dann aber nicht generell Querys gemeint sondern eher andere komplexe aktionen wie indizieren oder packen.
Wenn eine Abfrage zu lange dauert hat men im Regelfall im Statement was unpassend zusammengebaut. Ändere zum Test einfach mal die Reihenfolge der Einschränkungen. Wenn du irgendwo mit oder arbeitest, teil die beiden Teile auf und fasse sie mit Union zusammen. Das hat bei mir machmal echte Wunder bewirkt.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Für diesen Beitrag haben gedankt: BenBE
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 28.09.10 10:56
Ich hoffe, dass du längere Texte mit Satzzeichen schreibst.
Callback wurde schon genannt und besseres Design ebenfalls.
Die Optimierung von DB-Abfragen kann man auch mit verschiedenen Tools hinbekommen. Bei Oracle geht das mit "Explain Plan". Wie das bei anderen DBs aussieht, kann ich dir nicht sagen.
Übliche Fehler:
- Fehlender Index
- Ungünstige Reihenfolge der Bedingungen im Where-Bereich
- Kreuztabellen
- Zu viele Datensätze (weitere Einschränkungen erforderlich)
Für diesen Beitrag haben gedankt: BenBE
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Di 28.09.10 11:35
Eigentlich ist das mit dem Einbinden einer Fortschrittsanzeige doch recht einfach, oder?
Du suchst in Recordcount Datensätzen von Anfang an (First) fortlaufend (Next).
dann gehe doch so vor:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
| function Suche(was : string) : boolean; var i, n : longint; gef : boolean; Fortschritt : TProgressbar; begin gef := FALSE; with Datenbank do begin if not(active) then active := TRUE; n := Recordcount; if n=0 then begin result := FALSE; exit; end; Fortschritt.Min := 0; Fortschritt.Max := n; Fortschritt.visible := TRUE; first; i := 0; gef := FALSE; while not(gef) and not(eof) do begin Fortschritt.Position := i; ... Routinen zur Suche, speichern in gef! inc(i); next; end; end; Fortschritt.visible := FALSE; result := gef; end; |
Wie gesagt, nur ein Programmfragment. So in etwa sieht es bei mir aus, wenn ich Datenbanken abfrage. Oft setze ich dann auch noch Disablecontrols und Enablecontrols, um die Abfrage zu beschleunigen.
Ich hoffe, gedient zu haben
|
|
Sinspin
      
Beiträge: 1336
Erhaltene Danke: 119
Win 10
RIO, CE, Lazarus
|
Verfasst: Di 28.09.10 16:01
Ich denke, das ist voll am Problem vorbei.
Er sucht eine Möglichkeit um die Zeit zu überbrücken bis eine SQL Abfrage antwortet, also bis die Ausführung zum Programm zurückkehrt und die Ergebnismenge zum aubrufen bereitsteht.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
Horschdware
      
Beiträge: 744
Erhaltene Danke: 54
Win XP Pro, Win 7 Pro x64
Delphi 7, Delphi XE, C++ Builder 5, SAP R/3
|
Verfasst: Di 28.09.10 16:44
Ich denke, man sollte erst einmal klären
a) wieviele Datensätze gelesen werden sollen
b) wieviele Datensätze derzeit tatsächlich gelesen / angefasst werden
c) wieviel Zeit das Ganze benötigt
Dann müsste man sich überlegen, ob diese lange Bearbeitungszeit überhaupt notwendig ist.
Wie schon erwähnt lassen sich viele Selects durch Umbau oder Optimierung beschleunigen.
Nächster Schritt: Select Statements genau unter die Lupe nehmen.
Ganz allgemein: Projektion und restriktion möglichst früh und vor Join ausführen
_________________ Delphi: XE - OS: Windows 7 Professional x64
Für diesen Beitrag haben gedankt: BenBE
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Di 28.09.10 18:44
Horschdware hat folgendes geschrieben : |
Ganz allgemein: Projektion und restriktion möglichst früh und vor Join ausführen |
Ach, und ich dachte, genau anders herum. Oder ich habe dich misverstanden.
Kannst Du das anhand eines Beispieles erläutern?
Die Frage des Threadstellers impliziert, das der Server von vorneherein weiss, wieviele Daten er durchsuchen muss. Denn eine Fortschrittsanzeige ist nur dann möglich, wenn man vorher weiss, wieviel man zu durchsuchen hat.
Bei einer komplexen Abfrage ist das z.T. nicht deterministisch, d.h. am Anfang der Query nicht bekannt. Es kann auch sein, das ein Teil der Query eine externe Datenquelle beinhaltet.
Also: 'Richtige' RDBMS können das nicht. ADS ist nicht ganz so richtig, und eher (soweit ich mich entsinne) eine DBISAM mit SQL-Aufsatz. Ich kann mich dunkel erinnern, einmal damit gearbeitet, und etwas Ähnliches, wie eine Fortschrittsanzeige bei einer Query gesehen zu haben.
Aber nix gegen ADS.
_________________ Na denn, dann. Bis dann, denn.
Für diesen Beitrag haben gedankt: BenBE
|
|
Muck
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: Di 28.09.10 19:52
Hallo,
Oft vergisst man auch den LockType auf ReadOnly zu stellen und ein select auf eine groessere Tabelle (>500 MB) wird etwa 10 mal laenger dauern als mit einem ReadOnly Cursor. (z.B. bei ADO + MSSQL)
Sollte sich der select wirklich nicht optimieren lassen wie in den anderen Antworten beschrieben, dann waere eine Loesung unidirectional mit einem Server Cursor zu oeffnen solange man das Ergebnis nicht in einer grid anzeigen will.
Du kriegst dann die Kontrolle sofort zurueck und gehst mit eof Abfrage durch die Query. Waehrenddessen kannst Du dann die Fortschrittsanzeige (keine Prozentanzeige da Du RecordCount nicht kennst) laufen lassen.
Prior, First, Last ist dann nicht moeglich, ausserdem nicht RecordCount verwenden.
in Ado z.B.:
Delphi-Quelltext 1: 2: 3:
| ADOQuery1.CursorLocation:=clUseServer; ADOQuery1.LockType:=ltReadOnly; ADOQeury1.CursorType:=ctOpenForwardOnly; |
Das ist ne Loesung fuer die Fortschrittsanzeige, aber dennoch beschaeftigst Du den SQL Server mit einer langen Abfrage, die wahrscheinlich vermeidbar ist.
Fuer TQuery
Delphi-Quelltext 1:
| Query1.undDirectional:=true; |
Markus
Für diesen Beitrag haben gedankt: BenBE
|
|
|