Entwickler-Ecke

Datenbanken - SQL Befehle schneller senden


bbfan - So 29.01.06 20:35
Titel: SQL Befehle schneller senden
Hallo!

ich habe derzeit so um 20.000 Datensätze zu aktualisieren.
Habe ein primitive Schleife gebaut, die pro Runde einen SQL Update Befehl über ADO sendet.

Gibt es noch einen schnelleren Weg?


BenBE - So 29.01.06 21:02

Hast du den Transactions-Cache aktiviert? Das hilft wahre Wunde (15 Minuten für 250000 Datensätze auf 3 Sekunden) ohne den Source zu ändern.


bbfan - Mo 30.01.06 09:49

noch nie gehört... Wo/Wie aktiviere ich den?


alzaimar - Mo 30.01.06 10:04


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
MyADOConnection.BeginTrans;
Try
  For i:=0 To 1000000 do 
    MySQLCommand.Execute;

  MyADOConnection.CommitTrans; // Kein Fehler aufgetreten? Dann Alles übernehmen
Except
  MyADOConnection.RollbackTrans; // Ooops, alles rückgängig machen
End;


Transactionen sind ein Mittel auf der DBMS-Seite, um die Integrität der Daten sicherzustellen. Egal was, egal wie, entweder sind ALLE Änderungen der Transaktion übernommen worden, oder Keine. Selbst bei einem Stromausfall Mittendrin.

Das klassische Beispiel hierfür ist eine Banküberweisung;

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Begin Transaction
Try
  Betrag X von Konto A abziehen
  Betrag X auf Konto B gutschreiben
  Commit Transaction
Except
  Rollback Transaction
End


Andere Möglichkeiten der Performanceverbesserung:
Erzeuge eine Stringliste, und pack die SQL-Anweisungen da rein. Es gibt ein Limit für die Gesamtlänge, glaub ich.
Ich schicke jedenfalls immer ca 100 Zeilen per ADOCommand.Execute los. Das könnte auch noch mal Einiges bringen.


Udontknow - Mo 30.01.06 10:12

Hallo!

Weitere Performancegewinne erreichst du, indem du nicht das SQL-Statement selber dauernd abänderst, sondern mit Parametern arbeitest.

Cu,
Udontknow


Stefan.Buchholtz - Mo 30.01.06 11:44

Mit welcher Datenbank arbeitest du? Bei Oracle würde ich empfehlen, statt ADO die DOA-Komponenten ([url]allroundautomations.com[/url]) zu benutzen. Die unterstützen Array-DML, das heisst, du übergibst als Parameter der Query nicht einzelne Werte, sondern ein Werte-Array. Damit brauchst du das Statememnt nur einmal zu senden und die Datenbank führt es für jedes Arrayelement aus.

Stefan


Amiga-Fan - Mo 30.01.06 13:51

wo kann man den Transaktionscache denn einschalten?


bbfan - Mo 30.01.06 14:18

Das sind prima Vorschläge, die ich gleich mal ausprobieren werde.
Ich arbeite mit ADO zu einer AccessDatenbank hin.




Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
 MyADOConnection.BeginTrans;  
Try  
  For i:=0 To 1000000 do   
    TADOQuery.execSQL; 
  MyADOConnection.CommitTrans; // Kein Fehler aufgetreten? Dann Alles übernehmen  
Except  
  MyADOConnection.RollbackTrans; // Ooops, alles rückgängig machen  
End;


Bei mir wird der SQL Befehl über TADOQuery abgeschickt. Ist das so richtig?
Der TADOQuery wird zuvor mit dem Befehl addQuery.sql.add mit 1 SQL Befehl gefüllt und mit exec ausgeführt.
Was für mich ganz wichtig ist, ist das die Schleife auch bei fehlgeschlagenem SQL weiterläuft und auch die anderen SQL Befehle durchgeführt werden.