Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Beschleunigungstips für SQLite unter Android erwünscht (https://www.delphipraxis.net/192760-beschleunigungstips-fuer-sqlite-unter-android-erwuenscht.html)

sko1 17. Mai 2017 12:08

Datenbank: SQLite • Version: ? • Zugriff über: FMX TFDQuery

Beschleunigungstips für SQLite unter Android erwünscht
 
Hallo,

ich habe viele Datensätze in eine SQLite-Datenbank zu schreiben, unter Windows dauert das nur ca. 10 Sekunden,
unter Android, der eigentlichen Anwendung braucht der Anwender viel Geduld, da gehen schon mal bis 5 Minuten drauf um ca. 10000 Datensätze mit jeweils ca. 15 Feldern zu schreiben!

Jetzt suche ich Möglichkeiten das zu beschleunigen:

Bisher habe ich sinngemäß folgendes gemacht:

Delphi-Quellcode:
FDQuery.Append;
FDQuery.Edit;
FDQuery.fieldByName('xxxx').AsString := 'asdffghg';
FDQuery.post;
Jetzt habe ich alle INSERTS in einer Stringlist und arbeite diese so ab:

Delphi-Quellcode:
    FDQuery.SQL.Text := 'BEGIN TRANSACTION;';
    FDQuery.ExecSQL;
    for s := 0 to SQLList.Count - 1 do
    begin
      FDQuery.SQL.Text := SQLList[s];
      FDQuery.ExecSQL;
    end;
    // abschicken
    FDQuery.SQL.Text := 'COMMIT;';
    FDQuery.ExecSQL;
Das geht minimal schneller, vielleicht 4 anstelle 5 Minuten :cry:

Was ist bei mir die Bremse oder geht das auf einem Handy wirklich alles so langsam, hat jemand eine Idee wo ich ansetzen könnte?

Ciao
Stefan

Der schöne Günther 17. Mai 2017 12:16

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Testweise einmal ohne Transaktion probiert?

Auch: Kenne mich mit Datenbanken nicht so wirklich aus, aber konnte man Statements nicht irgendwie "preparen" und am Schluss nur für jeden Datensatz die Parameter neu setzen?

Olli73 17. Mai 2017 12:31

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Vor der Schhleife:
- Insert-Statement mit Parametern formulieren und der Query zuweisen
- Prepare aufrufen

In der Schleife:
- Parameter füllen
- ExecSQL ausführen

Dann muss das SQL nur 1 mal geparsed werden.

Dennoch finde ich den Unterschied Windows <-> Android zu hoch.
Was hast du denn für ein Android-Gerät?

Sherlock 17. Mai 2017 12:36

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
SQLite ist eventuell nicht die richtige Datenbank für das Datenvolumen?

Sherlock

sko1 17. Mai 2017 12:55

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Zitat:

Zitat von Olli73 (Beitrag 1371741)
Vor der Schhleife:
- Insert-Statement mit Parametern formulieren und der Query zuweisen
- Prepare aufrufen

In der Schleife:
- Parameter füllen
- ExecSQL ausführen

Dann muss das SQL nur 1 mal geparsed werden.

Dennoch finde ich den Unterschied Windows <-> Android zu hoch.
Was hast du denn für ein Android-Gerät?

Das ist ein recht betagtes Hannspree Tablet mit Android 4.4.2, wobei, auf meinem Galaxy S5 oder Galaxy Tab4 läuft es auch nicht wesentlich schneller...

Könntest Du bitte Deinen Tip mal in ein paar Beispielzeilen Code zeigen?
Prepare und Parameter sind mir momentan nicht geläufig, Datenbanken sind Neuland für mich.

Ciao
Stefan

Darlo 17. Mai 2017 13:03

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Hi,

hier ein Beispiel wie ich unter iOS und Android ganz gute Performance erreiche:
Delphi-Quellcode:

            mySQLQuery.Sql.Text := 'INSERT INTO jobVollmacht (pid, gesellschaft, art, zeitpunkt) '+
              'VALUES (:pid, :gesellschaft, :art, :zeitpunkt)';
            mySQLQuery.ParamByName('pid').AsString := dbModul.aktPid;
            mySQLQuery.ParamByName('gesellschaft').AsWideString := frmVuAuswahl.lbVuAuswahl.ListItems[i].Text;
            mySQLQuery.ParamByName('art').AsString := 'Teil';
            mySQLQuery.ParamByName('zeitpunkt').AsDateTime := now;
            mySQLQuery.Prepare;
            mySQLQuery.ExecSQL;

Olli73 17. Mai 2017 13:03

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Zitat:

Zitat von sko1 (Beitrag 1371744)
Könntest Du bitte Deinen Tip mal in ein paar Beispielzeilen Code zeigen?
Prepare und Parameter sind mir momentan nicht geläufig, Datenbanken sind Neuland für mich.

Delphi-Quellcode:
  FDQuery.SQL.Text := 'insert into TABELLE values (:Feld1, :Feld2, ... :FeldN)';
  FDQuery.Prepare;  
  for s := 0 to Anz - 1 do begin
    FDQuery.ParamByName('Feld1').AsString := 'Wert'; //oder noch schneller: FDQuery.Params[0].AsString := 'Wert';
    FDQuery.ParamByName('Feld2').AsInteger := Wert;
    ...
    FDQuery.ExecSQL;
  end;

Blup 17. Mai 2017 13:12

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Wenn deine Query auch mehrere SQL-Befehle gemeinsam als Skrip absenden kann, könnte das so schneller gehn:
Delphi-Quellcode:
 FDQuery.SQL.Text := 'BEGIN TRANSACTION;';
 // in "SQLList" müssen die einzelnen Statements bereits mit ';' abgeschlossen ein
 FDQuery.SQL.Add(SQLList.Text);
 FDQuery.SQL.Add('COMMIT;');
 FDQuery.ExecSQL;
http://docwiki.embarcadero.com/RADSt...tches_(FireDAC)

mkinzler 17. Mai 2017 13:22

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Könnte in disem Fall (SQlite) stimmen. Im Allgemeinen dütfte die Variante per Parameter (prepared Statement) aber schneller sein.

sko1 17. Mai 2017 13:27

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Danke, danke, danke!

Jetzt habe ich ja erst mal eine Weile zu testen, die Variante mit dem Parameters habe ich glaube ich verstanden, da muss ich jedoch etliches Umbauen.

Daher wird der erste Test mal alle Inserts per SQL.Add reinpacken und mit einem ExecSQL abarbeiten sein, mal sehen ob das funktioniert.

Danke auch für den Hinweis, das Parameters[index] schneller ist wie ParamByName, ich hätte bestimmt erst letzteres probiert

Ciao
Stefan

mjustin 17. Mai 2017 13:29

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Optimierungstipp von https://stackoverflow.com/a/28188228/80901

* eine Transaktion verwenden

:wink:

Blup 17. Mai 2017 14:38

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Transaktion hat er doch schon per SQL-Befehl.
Zu viele Inserts in einer Transaktion können aber auch bremsend wirken.

Mavarik 17. Mai 2017 15:49

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Also ich mache das so... ca. 45000 Datensätze und 37 Felder. Dauert ca 18-25 Sekunden je nach Device. Der Source ist noch aus den Anfängen... Heute würde ich es auch anders machen...

Delphi-Quellcode:
 
          SQLConnection.Open;

          Felder := MakeFieldDef(FRecordDef);

          SQLQuery.SQL.Text := 'BEGIN;';
          SQLQuery.ExecSQL(true);
 
           while not(SQLReader.eof) do
            begin
              SQLReader.ReadSQLCrypt; // Lade die Daten aus einer verschlüsselten Datei

              inc(Count);

              if (Count mod 100) = 0 then
                StatusProg('',100.0 / MaxSize * SQLReader.Position,FloattoStrF(100.0 / MaxSize * SQLReader.Position,ffFixed,7,2)+'%');

              D := SQLReader.GetSQLBytes;

              SQLQuery.SQL.Text := 'INSERT INTO '+FTableName+' ('+Felder+') VALUES (0,'+D+PostFields+');';
              try
                SQLQuery.ExecSQL(false);
              except
                StatusProg('EXCEPTION',0,'');
              end;
            end;

          StatusProg('',100.0,SIndexWait); // 'Erzeuge Index, Bitte warten...'
          SQLQuery.SQL.Text := 'COMMIT;';
          SQLQuery.ExecSQL(true);

          SQLConnection.Close;
Mavarik

Daniel 17. Mai 2017 16:00

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Die Array-DML von FireDAC könnte helfen. Sofern auf dem Gerät SQLite in Version >= 3.7.11 läuft, wird dieses Vorgehen auch von der DB unterstützt:

http://docwiki.embarcadero.com/RADSt..._DML_(FireDAC)

Mavarik 17. Mai 2017 16:03

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Zitat:

Zitat von Daniel (Beitrag 1371774)
Die Array-DML von FireDAC könnte helfen. Sofern auf dem Gerät SQLite in Version >= 3.7.11 läuft, wird dieses Vorgehen auch von der DB unterstützt:

http://docwiki.embarcadero.com/RADSt..._DML_(FireDAC)

ggf. Aber auf einem Device ist eh alles RAM... Wenn man sich das Ganze mal mit Instruments anschaut (ok ist iOS) sieht man wie sich der Speicher auf und ab baut...

sko1 18. Mai 2017 08:36

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Hallo,

nun habe ich einiges getestet, die Variante alle SQL's mit SQL.Add gemeinsam abzufeuern brachte kaum etwas, die Variante Prepare mit Parameters hat eine deutliche Beschleunigung gebracht :thumb:
Dabei habe ich die Parameter per Index und nicht per Name angesprochen.

Da ich verschiedene Inserts mit einer unterschiedlichen Anzahl von Feldern habe, dachte ich ich kann gleich zu Beginn
alle Parameter einstellen:

Delphi-Quellcode:
      FDQuery.Params[0].DataType := Tfieldtype.ftAutoInc;
      FDQuery.Params[1].DataType := Tfieldtype.ftString;
      FDQuery.Params[2].DataType := Tfieldtype.ftString;
      FDQuery.Params[3].DataType := Tfieldtype.ftString;
      FDQuery.Params[4].DataType := Tfieldtype.ftString;
...
Aber da kommt ein Index-Fehler!
Es sieht so aus als ob erst das SQL-Statement gesetzt werden muss und dann nur genau die Anzahl Parameter eingestellt werden darf die im SQL vorkommen?

Irgendwie möchte ich noch etwas an Verarbeitungszeit "herauskitzeln"!

Noch Ideen?

mkinzler 18. Mai 2017 09:52

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Ja. Die Parameterobjekte werden beim Prepare erzeugt. Die Typen musst Du auch nur einmal setzen.

Aviator 18. Mai 2017 10:39

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
Zitat:

Zitat von Sherlock (Beitrag 1371743)
SQLite ist eventuell nicht die richtige Datenbank für das Datenvolumen?

Sherlock

Das glaube ich weniger. Im Netz schwirren Aussagen rum, dass SQLite mit 50GB Daten problemlos funktioniert. Dementsprechend viele Zeilen und Spalten hat die Datenbank dann auch. :wink:

Es gibt eine alte Seite auf der SQLite HomePage. Dort werden Geschwindigkeiten verglichen in denen eine alte Version von SQLite schon sehr gut abgeschnitten hat. Allerdings steht auch in roter Schrift darüber, dass diese Seite nicht mehr aussagekräftig ist. Deshalb verlinke ich die hier jetzt mal nicht. Über Google kann man die aber sehr schnell selbst finden wenn man sie denn sehen möchte.

sko1 19. Mai 2017 10:56

AW: Beschleunigungstips für SQLite unter Android erwünscht
 
So, nachdem ich alle Eure Tips getestet und teilweise umgesetzt habe (je nach Verbesserung der Laufzeit) bin ich jetzt von meinen 4-5 Minuten auf ca. 20 Sekunden herunter, dazu ein Fortschrittsbalken für den Anwender und alles ist gut!

Danke für Eure Tips!

Ciao
Stefan


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:41 Uhr.

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