![]() |
Datenbank: Mariedb • Version: 10 • Zugriff über: UniDac
Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
Hallo in die Runde,
in meinem Lagerprogramm werden regelmäßig größere Mengen Kartonware auf festgelegte Plätze eingelagert. Größere Mengen sind 100 Stück, vielleicht werden es auch mal 200 aber eher sind es regelmäßig 20 - 50 Stück. Ich weiß, diese Mengen sind für eine DB eher Kleinstmengen und damit schnell verarbeitet. Die Notwendigkeit, sich mit der Verarbeitungsgeschwindigkeit zu beschäftigen liegt an einem höheren aufkommen an Arbeitsplätzen, die regelmäßig die DB nutzen und, jetzt neu, ein Außenlager, das per VPN die PC's dort ins lokale Netzt einbindet und/oder ein Remotedesktop als Arbeitsplatz. Das gibt dann doch immer mal wieder Fehler. Eine Möglichkeit sehe ich in der Verarbeitungsgeschwindigkeit des Update-Prozesses per SQL. Auf die Ausgestaltung des Netzwerks habe ich keinen Einfluss und DSL oder eine Standleitung bringt auch keine zuverlässige Geschwindigkeit bei der Verbindung. Bisher lese ich die einzulagernden Produkte per Scanner in eine Liste ein, es werden ein paar Daten aus einer anderen DB ergänzt und für die weitere Verarbeitung in einer MEM Table auf dem PC vorgehalten. Über ein SELECT werden alle freien Plätze im Lager in der entfernten MariaDb gesucht und über weitere Kriterien aus der vorher erstellten Liste wird dann passend zum Produkt diese Abfrage gefiltert und mit einem UPDATE... der erste Datensatz als Lagerplatz für das Produkt bestimmt. Gibt es keine passenden Plätze mehr (kein Datensatz entspricht den Kriterien) bekomme ich das mit und kann darauf reagieren. Ich habe jetzt mit einigen Varianten testweise mit 1000 Datensätzen herumexperimentiert: Die Update-Befehle in einer StringList gesammelt und dann an Query1.SQL.Text übergeben oder wie ![]() Diese Rückmeldung, ob, und wenn ja, wo jetzt das Produkt eingelagert werden soll benötige ich aber. Hat jemand eine Idee, Beispiel oder Lösung, wie ich das Umsetzen könnte?? Beste Güße Gerd |
AW: Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
Zitat:
Zitat:
Für mich läuft es im Grunde auf einen Vorher-Nachher-Vergleich hinaus. Es sei denn Devart hat da noch eine Option, die mir gerade nicht bekannt ist. |
AW: Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
Welchen Fehler bekommst du denn? Ein C/S Programm via VPN und ev noch WLAN kann so richtig langsam werden. Bei RDP solltest du das Problem aber nicht haben, oder?
Was ist das Problem eigentlich? Dauert das Update für die per VPN angebundenen zu lange? Behindern die Updates sich gegenseitig und machen das langsam oder weil Deadlock unmöglich? Du könntest die Updates in eine Sored Procedure übergeben, dann kannst du dir auch die Infos zurückgeben lassen, die du brauchst und die Daten müssen nicht via langsamen(?) VPN hin und her geschickt werden. |
AW: Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
Hallo,
und ich komme mal mit dem berühmten "Prepare" um die Ecke. |
AW: Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
Dank schon mal an dieser Stelle für die vielen Hinweise!
Zitat:
Eine konkrete Fehlermeldung habe ich bisher nicht bekommen. Wie gesagt, es gibt diesen Fehler zur Zeit nicht sehr oft. Aber ich erwarte, das es mehr Probleme geben wird, wenn an mehreren Rechnern enBlock Datensätze mit einem Update bearbeitet werden. Dem möchte ich mit einer Optimierung der Datenverarbeitung vorbeugen Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Grüße Gerd |
AW: Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
ad Stored Procedure: Da geht fast alles. Du kannst zB mehrere SQL Statements als Block übergeben und die SP arbeitet die der Reihe nach ab. Oder du übergibst nur IDs, die abgearbeitet werden sollen. Wie auch immer. Und zurück kannst du dir eine Struktur geben lassen, aus der du dir deine Infos wieder rausklaubst. Oder du benutzt eine Tabelle zum Datenaustausch. Da kenne ich jetzt sowohl MaraiDB als auch deine Anwendung zu wenig.
Aber wenn ich einen Tipp geben darf: Schau, dass du rausbekommst, was genau das Problem ist. Ändere keinen Code aufgrund ungeprüfter Vermutungen. :thumb: |
AW: Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
Sollte man nicht erstmal eine transaktionale Tabelle machen, sowas wie :
Datum/Uhrzeit | Menge (+/-) | ProduktId | .... Da trägt man ein, wenn was rein oder raus geht. und von dieser Tabelle erstellt man dann eine Zusammenfassung, errechnet durchschnittliche Einkaufspreise etc. Und die Tabelle sollte auch immer wieder erzeugbar sein von den verschiedenen Quellen wie Wareneingang, Versand, Produktion etc. alles jeder, der was reintut oder rausnimmt. |
AW: Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
Zitat:
Zitat:
Zitat:
|
AW: Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
Zitat:
Zitat:
Zitat:
Ich habe mir eine SP zusammengebastelt, die das macht was ich will: Ein Update bei einem Datensatz, der meinen Suchkriterien entspricht. Und ich bekomme die passenden Infos z.B. den Lagerplatz zurück. Und wenn kein freier Platz gefunden wurde, fehlt der Lagerplatz in der Rückgabe. Die SP ist in der Datenbank gespeichert. Allerdings ist das Problem, das das Update für mehrere Datensätze (mein eigentliches Problem) auch wieder zu lange dauert. Da bin ich mit einem Update per Batch und einer erneuten Abfrage der bearbeiteten Datensätze schneller. Ich habe für eine SP kein Bespiel gefunden, wie hier dann mehrere Datensätze mit einem ExecSQL an die Datenbank geschickt werden kann Hier die Stored Procedure, die ich für jeden Datensatz einzeln aufrufe
Code:
Der Aufruf in Delphi
CREATE DEFINER=`root`@`%` PROCEDURE `StoreInToPlaceUpdate`(
IN pStoreId int, IN pBuilding int, IN pRoom int, IN pSize int, IN pItemNbr VARCHAR(50), IN pCategoryNbr int, IN pAssemblyStatus tinyint, IN pStation int, IN pComment VARCHAR(255), IN pOrderNbr int, IN pSequenceNbr int, OUT oCount int, OUT oNumber int, OUT oPlace VARCHAR(255)) BEGIN SET @lagerid = '0'; SET @placeid = '0'; SELECT nr, COALESCE(CONCAT(floor, corridor, '-', field, compartment, '-', place), 0) AS aPlace FROM lager WHERE StoreId = pStoreId AND Building= pBuilding AND Room = pRoom AND WgSize = pSize AND ((ItemNbr = '0') AND (Lock = 0)) AND Deleted = 0 ORDER BY wgsize ASC, floor ASC, corridor ASC, place ASC LIMIT 1 INTO @lagerid, @placeid; UPDATE lager SET ItemNbr= pItemNbr, WgNbr = pCategoryNbr, Montage = pAssemblyStatus, Station = pStation, LgTimeStamp = NOW(), Comment = pComment, OrderNbr = pOrderNbr, SequenceNbr = pSequenceNbr WHERE nr = (@lagerid); SELECT @lagerid, ROW_COUNT() AS rCount, @placeid INTO oNumber, oCount, oPlace; END
Delphi-Quellcode:
Denn Output habe ich in ein txt Datei geschrieben(Auszug):
function StoreInToPlaceUpdate(pStoreId, pBuildingId, pRoomId: Integer; pSize,
pItemNbr: string; pCategoryNbr, pAssemblyStatus, pStation: Integer; pComment: string; pOrderNbr, pSequenceNbr: integer; out oPlace: string): Integer; var sp: TUniStoredProc; begin Result:= 0; try sp:= TuniStoredProc.Create(nil); sp.Connection := fMainForm.coMariaDb; sp.StoredProcName := 'StoreInToPlaceUpdate'; sp.PrepareSQL; sp.Params[0].AsInteger:= pStoreId; sp.Params[1].AsInteger:= pBuildingId; sp.Params[2].AsInteger:= pRoomId; sp.Params[3].AsString:= pSize; sp.Params[4].AsString:= pItemNbr; sp.Params[5].AsInteger:= pCategoryNbr; sp.Params[6].AsInteger:= pAssemblyStatus; sp.Params[7].AsInteger:= pStation; sp.Params[8].AsString:= pComment; sp.Params[9].AsInteger:= pOrderNbr; sp.Params[10].AsInteger:= pSequenceNbr; sp.ExecSQL; oPlace:= sp.Params[13].AsString; Result :=sp.Params[12].AsInteger finally end; FreeAndNil(sp); end;
Code:
Einen Index habe ich auf die Felder WgSize,floor,corridor, place gesetzt, wirklich gebracht hat das aber für diese SP nicht wirklich was.
1A-00-276 - 21734 - OrderNr:1180_65
1A-00-277 - 220398 - OrderNr:1180_66 1A-00-278 - 5279 - OrderNr:1180_67 0 - 21137 - OrderNr:1180_68 1A-00-279 - 21372 - OrderNr:1180_69 1A-00-280 - 21734 - OrderNr:1180_70 1A-00-281 - 21925 - OrderNr:1180_71 Zum Testen habe ich 1000 Updates abgeschickt, das braucht dann ca. 33000 ms, ein einfaches Update mit gleichem Ergebnis per Batch ist nach ca 200 ms fertig (alles unter gleichen Bedingungen getestet). Wie kann ich ein Batch Update per Stored Procedure umsetzen? Geht das überhaupt? Beste Grüße Gerd |
AW: Mehrere Datensätze mit SQL-Befehl Update schneller aktualisieren
ad Stored Procedure: Die SP hat wie du selber feststellst, nur Sinn, wenn mehrere Datensätze abgearbeitet werden. Wenn du jeden Satz einzeln abarbeitest, ist das nur Overhead. Ich würde die IDs ALLER Datensätze, die du bearbeiten möchtest, der SP auf dem Server übergeben.
Siehe hier: ![]() Oder du stellst für das UPATE WHERE IN die IN Clausel in Delphi zusammen und übergibst die an die SP. Aber nochmal hingewiesen: Schau, dass du rausbekommst, was genau das Problem ist (= was dauert denn so lange?). Ändere keinen Code aufgrund ungeprüfter Vermutungen. Wenn das Aktualisieren selbst so lange dauert, hilft dir die SP auch nicht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz