Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Sylence

Community-Fossil

  • »Sylence« ist der Autor dieses Themas

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

1

20.05.2012, 22:57

[C#] SQLite extrem langsam

Hallo zusammen!

Ich stolper gerade über etwas, bei den ich nicht so recht weiter weiß.
Und zwar will ich einige Datensätze ein einem Rutsch in eine SQLite datenbank schreiben (über den System.Data.SQLite wrapper).

Das ganze sieht Code-Technisch in etwa so aus:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
StringBuilder sb = new StringBuilder();
sb.Append( "BEGIN TRANSACTION;" );
sb.Append( "DELETE FROM Tabelle;" );
foreach( ... )
{
   sb.Append( "INSERT INTO Tabelle ...;" );
}
sb.Append( "COMMIT;" );

using( DbCommand cmd = connection.CreateCommand() )
{
   cmd.CommandText = sb.ToString();
   cmd.ExecuteNonQuery();
}


Für 16.684 Datensätze braucht das ganze allerdings 4:41 min...
Diese Zeit verbringt er auch nur in dem "ExecuteNonQuery()" und nicht etwa in der schleife, die den Query bastelt

Laut dem FAQ Eintrag von sqlite.org sollte das ganze allerdings nicht so lange dauern.
Interessant ist auch, dass die von ca. 60 Transaktionen pro Sekunde reden, was ziemlich genau dem entspricht was ich hier habe.

Allerdings sollte ich doch durch das "BEGIN TRANSACTION" .. "COMMIT" die ganzen Queries in einer Transaktion abwickeln...

Überseh ich irgendwas?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

21.05.2012, 00:32

Es kommt ja immer darauf an, was in der Transaktion geschieht.
Wenn du da jetzt 100 MB große Daten reinschreibst, dann werden 60 pro Sekunde wohl kaum schaffbar sein!
Wie komplex ist dein Tabelle?

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

3

21.05.2012, 00:38


Allerdings sollte ich doch durch das "BEGIN TRANSACTION" .. "COMMIT" die ganzen Queries in einer Transaktion abwickeln...

Du scheinst das wohl falsch zu verstehen. Transactions sind keine Möglichkeit, um etwas schneller ("in einem Rutsch") zu machen, sondern um Konsistenz zu wahren. Wenn nicht unbedingt alle Modifikationen kritischerweise ganz oder gar nicht geschehen müssen, dann brauchst du das nicht und ist wahrscheinlich schneller.

Edit:
Siehe dazu z.B. hier.

Edit2:
Ok, möglicherweise ist es doch auch schneller/gleich schnell. Kommt wohl auf die Implementierung an, aber die Idee ist hier grundsätzlich schon die Konsistenz und nicht unbedingt Performance.

Edit3:
Was soll Zeile 3 genau? Du willst ja ein Haufen Zeugs reinschreiben. Warum hast du da noch ein delete drin?

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »drakon« (21.05.2012, 00:50)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

21.05.2012, 06:34

Wie wäre es mit einem Bulk-Insert statt einem Insert-Statement pro Datensatz? Kann SQLite das nicht? Denn das macht einen gewaltigen Unterschied.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

5

21.05.2012, 06:41

Bevor hier wild vermutungen angestellt werden, solltest du vllt die Spalten angezeigt werden. Ansonsten vermute ich wie BlueCobolt. dass dein Statement einfach ungünstig ist und optimiert werden kann. Prinzipiell ist wohl SQLite im Vergleich zu einer richtigen SQL-Datenbank merklich langsamer. Zeig doch mal ein konkretes Statement, welches 3-4 Zeilen beinhaltet.

Sylence

Community-Fossil

  • »Sylence« ist der Autor dieses Themas

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

6

21.05.2012, 11:37

@drakon: Klar sind Transaktionen eigentlich dafür gedacht Konsistens zu bewahren. Nur durch den FAQ Eintrag bin ich halt darauf gekommen.

Das delete ist da, weil es sich bei der Tabelle um Dateien auf dem Rechner handelt und das für mich der einfachste Weg war dafür zu sorgen, dass nur aktuelle Daten in der Tabelle stehen ohne vorher gucken zu müssen ob alte Dateien gelöscht wurden oder neue hinzugekommen sind.

Die Daten sind auch nicht sonderlich groß, weil es halt eben nur Dateipfade und Namen sind:

Quellcode

1
2
3
4
5
6
7
BEGIN TRANSACTION;
DELETE FROM Speedy_Files;
INSERT INTO Speedy_Files (Command, Name, [Type], Icon, Arguments) VALUES ( 'c:\windows\system32\control.exe', 'Default Programs', 'exe', 'C:\Windows\system32\imageres.dll,-24', '/name Microsoft.DefaultPrograms' );
 INSERT INTO Speedy_Files (Command, Name, [Type], Icon, Arguments) VALUES  ( 'c:\windows\system32\wuapp.exe', 'Windows Update', 'exe', 'C:\Windows\system32\wucltux.dll,0', 'startmenu' ); 
 INSERT INTO Speedy_Files (Command, Name, [Type], Icon, Arguments) VALUES ( 'c:\program files (x86)\utorrent\utorrent.exe', 'µTorrent', 'exe', 'c:\program files (x86)\utorrent\utorrent.exe,0', '' );
 INSERT INTO Speedy_Files (Command, Name, [Type], Icon, Arguments) VALUES  ( 'c:\program files (x86)\freemind\freemind.exe', 'FreeMind', 'exe', 'C:\Program Files (x86)\FreeMind\Freemind.exe,0', '' );
COMMIT;


Wobei mir da gerade auffällt, dass ein Primärschlüssel der Tabelle wohl gut tun würde :whistling:

Bulk-Inserts werden angeblich von SQLite unterstützt, aber irgendwie hab ich das noch nicht zum laufen bekommen.

Ich werde mal weiter rumprobieren.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »drakon« (21.05.2012, 11:49) aus folgendem Grund: dot -> drakon (warum verwechseln uns alle?!)


TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

7

21.05.2012, 12:10

Wenn man auf der Seite von SQLite schaut gibt es viele Optimierungseinstellungen. Vielleicht solltest du dort mal stöbern, was für dich relevant ist - neben bulk Inserts.

Sylence

Community-Fossil

  • »Sylence« ist der Autor dieses Themas

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

8

21.05.2012, 15:19

So Bulk inserts haben bei mir nicht funktioniert, weil ich ne alte SQLite Version installiert hatte...
Das hat mein Performanceproblem dann auch schon behoben. (Dauert jetzt im Schnitt 3 Sekunden, womit ich leben kann)
Dabei hab ich aber auch einige interessante Sachen zur Optimierung von SQLite erfahren :)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

21.05.2012, 15:41

Hehe, von 4:41 auf 0:03. Na das klingt doch sinnvoll. ;)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige