Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Progress-Updates während einer Query (https://www.delphipraxis.net/209024-progress-updates-waehrend-einer-query.html)

Medium 15. Okt 2021 10:39

Datenbank: MariaDB • Version: - • Zugriff über: MyDAC

Progress-Updates während einer Query
 
Moin!
Für einen Pflegelauf in einer DB muss ich mehrere Tabellen mit sehr vielen Records kopieren. Ich setze mit einer TUniQuery ein SQL der Art
Code:
INSERT INTO foo (SELECT * FROM bar WHERE x=y)
ab. Das nudelt dann über Millionen von Zeilen, was mitunter etwas dauert. Ich würde gern den Fortschritt dieser Operation anzeigen, kann aber kein OnProgress Event o.ä. bei der Komponente finden.
Alles, was ich bisher im Netz fand, bezog sich lediglich auf das Selecten von großen Datenmengen. Das hilft hier glaube ich nicht.

Weiß jemand Rat? Danke!

himitsu 15. Okt 2021 11:04

AW: Progress-Updates während einer Query
 
Threads? :roll:

Entweder das Query (mit Connection) im Thread
oder die Warteanzeige im Thread.


Für den Fortschritt selber das Query aufteilen,
also jeweils X Datensätze kopieren.

Jasocul 15. Okt 2021 11:23

AW: Progress-Updates während einer Query
 
Gab es nicht mal eine TBatchMove-Komponente mit Callback? Damit sollte es doch eigentlich gehen. Du nutzt ja TUniQuery. Da sollte TCRBatchMove dabei sein. Dort gibt es ein OnBatchMoveProgress

Ansonsten würde ich den Prozess sowieso nicht auf einem Client ausführen, wenn so große Datenmengen verarbeitet werden sollen. Eventuell bietet sich auch noch eine Stored Procedure an. Das wäre von der Performance auf jeden Fall die bessere Variante.

Medium 15. Okt 2021 12:00

AW: Progress-Updates während einer Query
 
Zitat:

Zitat von himitsu (Beitrag 1496108)
Threads? :roll:

Entweder das Query (mit Connection) im Thread
oder die Warteanzeige im Thread.


Für den Fortschritt selber das Query aufteilen,
also jeweils X Datensätze kopieren.

Genau das will ich gern vermeiden, da es ziemlich aufwendig wäre diese Zerteilung noch vorzunehmen, und vor allem das ganze Gethreade zu programmieren. (D2007 war da ja noch nicht so komfortabel.) Und zudem wird es dadurch am Ende ja noch langsamer. Das wäre die Sache nicht wert.

Zitat:

Zitat von Jasocul
Gab es nicht mal eine TBatchMove-Komponente mit Callback? Damit sollte es doch eigentlich gehen. Du nutzt ja TUniQuery. Da sollte TCRBatchMove dabei sein. Dort gibt es ein OnBatchMoveProgress

Ansonsten würde ich den Prozess sowieso nicht auf einem Client ausführen, wenn so große Datenmengen verarbeitet werden sollen. Eventuell bietet sich auch noch eine Stored Procedure an. Das wäre von der Performance auf jeden Fall die bessere Variante.

Soetwas finde ich bei mir leider nicht. Wie oben geschrieben muss ich hierfür auf D2007 zurückgreifen, entsprechend alt ist auch die Uni-Version. Eventuell gab es das da einfach noch nicht :?
Bei einer SP dürfte es noch schwieriger sein, an einen Fortschritt zu kommen gell? Zumal: Wird nicht ohnehin eigentlich alles was im o.g. Statement, was ja ein Einzeiler ist, serverseitig ausgeführt? Der Client setzt doch bloß das Statement ab und wartet dann auf dessen Beendigung oder nicht?

himitsu 15. Okt 2021 15:12

AW: Progress-Updates während einer Query
 
SP: Ja, genauso ... alles im Server und raus bekommst'e Infos nur mit asynchronen Sachen über ein zweites Query. (falls Maria sowas kann)


TCRBatchMove:
Im Prinzip sind das zwei Queries.
* dein SELECT
* und ein "SELECT * FROM foo WHERE false" mit Insert/Append + Post
* * oder ein INSERT INTO mit Parametern + Execute
* und dann Datensatz für Datensatz rüberkopieren

Medium 15. Okt 2021 15:32

AW: Progress-Updates während einer Query
 
Ähm ja, das wird dann deutlich zu langsam. Da ich das ganze eh nur ca. alle halbe Jahre mal machen muss, und den Vorgang gerade angestoßen habe damit er übers Wochenende (hoffentlich) fertig wird, lege ich das "Komfort-Vorhaben" mal ad acta.

Aber wundert mich schon, dass es da offenbar keine Standard-Schnittstelle gibt, über die SQL-Server einen Fortschritt an seine Clients senden kann. Manchmal hat man eben keine hübschen kurzen kleinen Statements, gerade bei so Wartungsläufen.

himitsu 15. Okt 2021 15:52

AW: Progress-Updates während einer Query
 
Mach es wie der Explorer beim Suchen.
* schätze wie lange ein Datensatz braucht
* multipliziere es mit der Anzahl
* dann tu so, als wäre die Anzeige real
** ist es früher fertig, dann den rest schnell vorspulen
** dauert es länger, dann die restlichen 5% extrem langsam laufen lassen :stupid:
* und dann lass die Copy-Aufgabe komplett unabhängig vom Fortschritt laufen

dataspider 15. Okt 2021 15:57

AW: Progress-Updates während einer Query
 
Also mit Fierebird hab ich das mal mit einer Procedure gemacht.
Ich habe einfach eine selectable SP geschrieben und in der Anwendung durchlaufen (select * from sp_name)
und dann mit while not Query.eof do...

Und in der Procedure dann halt zur Ausgabe (suspend) die Änderungen in den Daten mitgemacht.

Heute würde ich mich nicht mehr für sowas verbiegen, zumal es auch immer weniger perfomant ist.

Frank

jobo 15. Okt 2021 22:25

AW: Progress-Updates während einer Query
 
Wenn sich das ausschließlich auf dem Server abspielt und Du nichts zerhacken willst, also eine vollständige Transaktion, dann wären autonome Transaktionen für Wasserstandsmeldungen hilfreich. Gibts bei Oracle und Postgres, weiter wüsste ich nicht.
Aber das Netz weiß mehr, hier eine Idee, die das ähnlich einer autonomen Transaktion durch eine andere Engine macht, für mySQL, vielleicht gibt es die Engine auch für Maria und es ist für den Einsatzzweck geeignet:
https://dba.stackexchange.com/questi...ction-in-mysql
Wahrscheinlich nur per SP, die selbst irgendwie stückelt bzw. einen Cursor über die gesamte Menge auf macht und Zwischenstände/Counter über die andere Engine wegschreibt.

himitsu 16. Okt 2021 00:04

AW: Progress-Updates während einer Query
 
In Postgres gibt es die FOREIGN DATA WRAPPER (FDW) und DBLINK,
damit kann man Verbindungen zu anderen DBMS aufbauen, aber auch zum Eigenen und sogar zu/in sich selbst.

So kann man innerhalb eines Selects/Transaction parallel eine weitere Connection öffnen und dort z.B. ein INSERT/UPDATE oder ein NOTIFY absetzen, dessen Transaktion fertig wird, vor/während der Eigenen.

Somit lässt sich dann über ein weiteres SELECT der Status vom Client abfragen, oder eine Notification zum Client senden.
Über eine zusätzliche Connection im Client, weil die Erste hängt ja noch.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:23 Uhr.
Seite 1 von 2  1 2      

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