German SQL - Löschen vieler Zeilen einer Tabelle

kkolle

Member
Licensed User
Longtime User
Hallo!

Ich lösche aus einer SQL-Tabelle innerhalb eines Services viele Zeilen aus einer Tabelle.

Frage: Kann mir jmd. sagen, warum das Activity trotzdem "einfriert"?

Vielen Dank!!

B4X:
Sub Service_Start(StartingIntent As Intent)

   For c = 0 To SocketService.DataForTransactionMap.Size - 1
      Database.mySQL.ExecNonQuery2("DELETE FROM DBLog WHERE id = ?", Array As String(SocketService.DataForTransactionMap.GetKeyAt(c)))

   Next
   
   SocketService.DataForTransactionMap.Clear

End Sub
 

Kiffi

Well-Known Member
Licensed User
Longtime User
viele Einzel-Delete-Anweisungen können in SQLite schon mal 'n Stückchen
dauern. Versuch's mal wie folgt:

B4X:
Dim IDs As String
For c = 0 To SocketService.DataForTransactionMap.Size - 1
 IDs = IDs & SocketService.DataForTransactionMap.GetKeyAt(c))
 If c < SocketService.DataForTransactionMap.Size - 1 Then
  IDs = IDs & ", "
 End If
Next

Database.mySQL.ExecNonQuery("DELETE FROM DBLog WHERE id In " & IDs)

Grüße ... Kiffi
 

kkolle

Member
Licensed User
Longtime User
Hi!

Danke für die Antwort! An die Optimierung im SQL habe ich noch garnicht gedacht :) Mich wundert halt nur, dass trotz Service meine Activity einfriert.

Ich werde es testen. Allerdings mit einem StringBuilder statt einem String. Sonst generiere ich dort die nächste "Bremse".
 

corwin42

Expert
Licensed User
Longtime User
Mich wundert halt nur, dass trotz Service meine Activity einfriert.

Weil ein Service im gleichen Thread ausgeführt wird wie die Activity. Um es "wirklich" im Hintergrund zu haben, müsstest Du einen eigenen Thread starten.

Die Lösung von Kiffi könnte auch langsam sein, weil ein recht komplexes statement aufgebaut wird.

Ich würde um den ganzen Block eine Transaktion packen:

B4X:
Sub Service_Start(StartingIntent As Intent)

    Database.mySQL.BeginTransaction
    For c = 0 To SocketService.DataForTransactionMap.Size - 1
        Database.mySQL.ExecNonQuery2("DELETE FROM DBLog WHERE id = ?", Array As String(SocketService.DataForTransactionMap.GetKeyAt(c)))

    Next
    
    Database.mySQL.TransactionSuccessful
    Database.mySQL.EndTransaction

    SocketService.DataForTransactionMap.Clear
End Sub

Aber wie gesagt, wenn es Deine Activity nicht beeinflussen soll, muss Du das in einem eigenen Thread machen.
 
Last edited:

kkolle

Member
Licensed User
Longtime User
@Kiffi:

Vielen Dank! Der "Umbau" im SQL-Statement war schon mal ein Schritt in die richtige Richtung!

Jetzt dauert das Löschen von 200 Datensätzen ca. 100 ms. In der GUI merkt man also (fast) nichts davon!

@corwin42:

Ahhh ... OK! Du hast nicht zufällig ein kleines Thread-Beispiel rumliegen? Oder gibt es schon eins im Forum?
Das mit der Transaktion werde ich ebenfalls mal testen!!
 

corwin42

Expert
Licensed User
Longtime User
Ahhh ... OK! Du hast nicht zufällig ein kleines Thread-Beispiel rumliegen? Oder gibt es schon eins im Forum?
Das mit der Transaktion werde ich ebenfalls mal testen!!

Ich denke mal, dass Andrew bei seiner Library eins bei gepackt hat. Threading Library

Ich musste bisher noch nichts in einem eigenen Thread machen. Aber ich meine, es war nicht so schwierig.
 

kkolle

Member
Licensed User
Longtime User
Mit einer Transaktion dauert das Löschen von 200 Datensätzen ebenfalls ca. 100 ms.

Habe die Library von Andrew runtergeladen und werde es einbauen. Sieht wirklich einfach aus!

Vielen Dank für Eure Hilfe!
 
Top