sehr viele Daten in einer MySQL Datenbank überprüfen/schreiben

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@boeserkorn: Dein Code ist fast nicht lesbar. Lesbarer Code ist aber wichtig, um ihn zu verstehen, um Fehler zu finden und um erst gar keine Fehler zu machen. Kunde, sunnyportal_ID, Datenbank, AnlagenID und vkn scheinen alles Listen zu sein, die über Daten enthalten, die über ihren Index zusammengehören. Das ist ein schlechtes Konzept, da, sobald eine der Listen nicht synchron mit den anderen geändert wird, unauffindbare Fehler entstehen. Besser ist es eine Liste mit strukturierten Objekten (tuple, namedtuple, wörterbuch) zu haben.

Was soll dieses Zuweisen von Werten an Variablen, um sie gleich in der nächsten Zeile wieder zu überschreiben (Zeile 17 oder 21)?

Zeile 22: f ist ein schlechter Name. Variablennamen sollten aussagekräftig sein.
Zeile 25: Du suchst os.path.basename statt replace.
Zeile 52, 60, etc.: niemals Variablen in SQL-Statements hineinformatieren. Damit kannst Du leicht Deine ganze Datenbank kaputt machen (entweder durch einen böswilligen Nutzer, oder unabsichtlich). Parameter werden als zweites Argument an execute übergeben. Nebenbei, die ganzen str-Aufrufe sind überflüssig.
Zeile 55: wenn man nur ein Ergebnis aus einer SQL-Abfrage erwartet, nimmt man fetchone.
Zeile 61: Datenbanken können mit verschiedenen Typen umgehen, datetime-Objekte werden Automatisch zu TIMESTAMPS, Zahlen bleiben Zahlen.
Zeile 63: ein commit nach jedem Update, macht die Sache nicht gerade schneller.
Zeile 72: pass ist hier nutzlos.

Du hast jetzt nicht nur ein UPDATE sondern auch noch ein SELECT, so dass Du alle Datenbanksuchen doppelt machst.

Das eigentlich wichtige bei Deinem Problem, das Datenbankschema, hast Du noch nicht gepostet.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

INSERTs und UPDATEs die nur eine Zeile verändern ist schonmal grundsätzlich nicht schnell, erst recht nicht wenn du jedesmal eine ganze Transaktion machst. Du nutzt die Datenbank hier in einer sehr ineffizient Weise und dass kostet massiv an Performance.

Um dies etwas zu verdeutlichen: Beruflich bin ich mitverantwortlich für die Verarbeitung von den Ergebnissen eines Optimierungsprozeses der um die 12GB an Daten und hunderte Millionen von Zeilen produziert, dass lässt sich in ~45min in eine MySQL Datenbank kopieren.

Selbst die 1.5h sind unglaublich langsam, da gibt es massives Optimierungspotential.

Um tatsächlich zu sagen wo konkret es hakt müsste man sich die Query Pläne ansehen aber ich würde davon ausgehen dass du keinen Index auf anlagenpv_idAnlagenPV hast. Den anzulegen sollte die Performance schon wesentlich verbessern.

Idealerweise hättest du die Daten als CSV vorliegen und würdest sie dann mit COPY (Postgres) oder LOAD DATA INFILE (MySQL) in die Datenbank kopieren ggfs. in eine temporäre Tabelle. Du könntest dann mit INSERTs und DELETEs (statt UPDATE) arbeiten um die Tabelle in nur wenigen Statements zu aktualisieren. Solche "großflächigen" Änderungen sind wesentlich effizienter und schneller als Zeile für Zeile zu arbeiten.
boeserkorn
User
Beiträge: 16
Registriert: Freitag 22. September 2017, 19:46

@Sirius3 Lasse bitte deine Kommentare, du kritisiert nur und gibts mir nicht wirklich Ratschläge.


@Dasich würdest du mir helfen den Ablauf vernümftig hinzu bekommen?

das mit den temp_Tabellen usw. verstehe ich nicht wirklich und blicke da nicht durch.

für mich war das Reihe für Reihe am leichtesten das umzusetzten um meine Ziele zu erreiche , nun ist es aber so groß geworden das ich mich nur noch mit importieren beschäftige.

würde mich freuen
Benutzeravatar
/me
User
Beiträge: 3552
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

boeserkorn hat geschrieben:@Sirius3 Lasse bitte deine Kommentare, du kritisiert nur und gibts mir nicht wirklich Ratschläge.
Doch, gibt er. Zum Beispiel: "Dein Code ist fast nicht lesbar." inklusive Hinweisen, wie man es besser machen kann. Du nimmst dir aktuell Leser und damit potenzielle Helfer weg. Mich hat ein Blick auf den Code davon abgeschreckt, mich weiter mit der eigentlichen Frage der Performance zu beschäftigen.
boeserkorn
User
Beiträge: 16
Registriert: Freitag 22. September 2017, 19:46

die Tabelle habe so erstellt und danach nochmal geändert, leider bekomme ich "idLastgang" nicht geändert, so das er nicht mehr als PrimaryKey eingetragen ist.

es würde sonst die Routine funktionieren
[codebox=mysql file=Unbenannt.sql]INSERT INTO eisman10.lastgang (Viertelstunde, lastgangwert, anlagenpv_idAnlagenPV) VALUES ('2017-09-01 00:00:00', 0.555,1)
ON DUPLICATE KEY UPDATE Viertelstunde = '2017-09-01 00:00:00', lastgangwert = 0.500;[/code]

ich bin kein Profi, das weiss ich selber. alles was ich bis jetzt gelernt habe ist entweder aus der Schulzeit/Ausbildung oder ich habe mir es mühevoll in der Freizeit dazu gelernt, durch probieren und erfragen, überwiegend aber durch rumprobieren.
klar ist nicht alles perfekt was ich mache, klar sind meine Variablen ab und zu mal komisch benannt, aber es ist doch egal ob die Variable Viertelstunde oder Messzeitpunkt heißt, solange ich weiss in welchen Bezug sie gehört und Viertelstunde ist für mich besser und kann ich mir besser merken.

[codebox=mysql file=Unbenannt.sql]CREATE TABLE IF NOT EXISTS `lastgang` (
`idLastgang` INT(11) NOT NULL AUTO_INCREMENT,
`Viertelstunde` DATETIME NULL DEFAULT NULL,
`lastgangwert` FLOAT NULL DEFAULT NULL,
PRIMARY KEY (`idLastgang`))[/code]


[codebox=mysql file=Unbenannt.sql]ALTER TABLE `lastgang`
ADD COLUMN `anlagenpv_idAnlagenPV` INT(11) NOT NULL AFTER `ZPB`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`idLastgang`, `anlagenpv_idAnlagenPV`),
ADD INDEX `fk_lastgang_anlagenpv1_idx` (`anlagenpv_idAnlagenPV` ASC);
ALTER TABLE `lastgang`
ADD CONSTRAINT `fk_lastgang_anlagenpv1`
FOREIGN KEY (`anlagenpv_idAnlagenPV`)
REFERENCES `anlagenpv` (`idAnlagenPV`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;[/code]
Antworten