SQLite-Performance

T

Tom299

Stammgast
122
Hi,

ich hab gerade ein großes Performance-Problem in meiner App festgestellt: Die ganze Zeit habe ich mit "normalen" Daten getestet, die Anwendung lief einwandfrei ohne spürbare Verzögerungen beim Anzeigen von Daten in Listen.
Das waren Daten im Bereich von 100 - 300 Datensätzen.

Jetzt haben wir einen Stresstest initiiert und 5000 Datensätze eingespielt. Meine Anwendung bleibt jetzt erst mal "hängen" (Daten werde nicht im Thread gelesen, war bis jetzt nicht notwendig) und nach mehreren Sekunden bzw. manchmal nach bestätigen von "Warten" anstatt "Anwendung beenden" kommen dann irgendwann die Daten bzw. ein leeres Grid, wenn keine Datensätze gefunden wurden.

Ich hab das jetzt mal lokal auf dem PC mit SQLite Expert Prof. getestet, da geht das Abfragen wie gewohnt sehr zügig.

Kann das am RAM des Handys liegen oder kann man irgendwelche Einstellungen zur DB machen, damit die Performance gesteigert wird?

Ich bin ehrlich gesagt etwas schockiert, daß die DB scheinbar nicht mit 5.000 Datensätzen klar kommt, wobei 5.000 jetzt ja keine allzu große Anzahl an Daten ist ...

Jemand nen Tip für mich?


Gruß,
Tom
 
naja erstmals Threads verwenden.

alles was länger dauern könnte, muss in threads. auch wenn es mit 100 datensätzen schnell geht. es wird noch immer eine datei gelesen und das kann aus irgendwelchen gründen auch mal länger dauern. wenn du viele user hast, tritt das dauernd irgendwo auf und die user werden damit keinen spaß haben.

zweitens:
nutzt du transaktionen? das beschleunigt abfragen ungemein. versuchs mal
 
Transaktionen hatten wir anfangs mal versucht, da kam aber immer ne komische Fehlermeldung daß er was nicht sql-mäßig kompilieren kann oder so. weiß nicht mehr genau, zu lange her ...

Aber nur zum LESEN braucht man doch keine Transaktionen, oder seh ich das grad falsch?

Das Auslagern in Threads läßt meine anwendung dann zwar nicht "hängen", aber die Liste bleibt ja erst mal leer und der Nutzer denkt er hat keine Daten und drückt gleich wieder den Back-Button ... es sei denn ich zeig ihm nen Progress-Dialog an, das wär ne Möglichkeit ... aber gefällt mir nicht so richtig.

Gibts sonst kein Tuning für die DB? Wir benutzen extra schon Views in der DB, damit es schneller und komfortabler geht oder gehen sollte ;-)
 
naja dann zeig mal her was du genau machst. wir können es hier nicht erraten :)

du sagst "nur zum lesen braucht man keine transaktionen"

das ist korrekt. aber ein SELECT statement braucht auch nicht so lange wie du es beschreibst. da muss mehr laufen, von dem wir nichts wissen.
 
Hier kannst du näheres über den Fehler erfahren ;-).
 
swordi schrieb:
aber ein SELECT statement braucht auch nicht so lange wie du es beschreibst. da muss mehr laufen, von dem wir nichts wissen.
Das dürfte vom Statement und den Datenstrukturen abhängen. Aber ohne Datenbankmodell / Tabellendefinitionen und eben das SELECT-Statement wird es schwer, hier eine Aussage zu treffen.
 
Was mir so beim groben Überfliegen auffällt:

- Lass die Sortierung im View weg (und mach das bei der eigentlichen Abfrage, im Moment sortierst du nämlich doppelt)
- Versuche SubSelects bei der Spaltenrückgabe zu vermeiden und binde diese, wenn möglich über JOINS mit ein (das sollte zumindest bei der Tabelle Termin und den MAX-Abfragen möglich sein).

- Und in Java: Vermeide String-Verkettungen und nutze StringBuffer oder StringBuilder.
 
  • Danke
Reaktionen: Tom299
Thyrion schrieb:
Das dürfte vom Statement und den Datenstrukturen abhängen. Aber ohne Datenbankmodell / Tabellendefinitionen und eben das SELECT-Statement wird es schwer, hier eine Aussage zu treffen.


ja klar, aber es kann nie so lange dauern, dass das beschriebene verhalten auftritt.
 
Tom299 schrieb:
Meine DB-View: SELECT B.Name as Benutzer, M.Name as Mandant, M.Mandant_ID, art.Bezeichnung as - Pastebin.com
Mein Code-Ausschnitt: [Java] String sql = "Select * from viewAuftraege" + " where Mandant_ID in (" - Pastebin.com

Das Ausführen des SQL an sich geht innerhalb 1 Sekunde, wie ich gerade beim Testen gesehen habe -> dataBase.rawQuery(sql, null)

Aber das Durchlaufen des Cursors -> c.moveToNext() dauert sage und schreibe 43 Sekunden ...

dann ist der threadtitel wohl falsch. sqlite ist schnell - java ist langsam :D

ich habe bemerkt, dass wenn man viele objekte erzeugt, dass sehr an die performance geht. eventuell hast da auch noch optimierungspotenzial
 
Erst mal Danke für Eure Bemühungen :)

Also das mit dem doppelten Sortieren war mir gar nicht aufgefallen ... hab die Sortierung aus der View entfernt und siehe da, nur noch 4s anstatt 44s!!!

Das mit den Sub-Selects muß ich mal genauer untersuchen, ob das mit einfachen Joins geht.

String-Buffer benutz ich eher selten, ich denke beim Aufbauen des SQL-Strings braucht man das nicht wirklich, oder? ;-)

@Swordi: Dass Java-Objekte Performance kosten können, hab ich schon zu Java-Zeiten erlebt. Hatte hier im Code mal die Objekt-Erzeugung auskommentiert, aber die Performance war unverändert bei 44s, was mich etwas verwundet, aber ok ...
 
na dann hast schonmal die zeit auf zehntel gedrückt. damit kann man bei mehreren tausend datensätzen schon eher leben.

ein bisschen was wirst sicher noch drücken können.

einen schönen lade indicator und der user ist glücklich :D
 
Das mit dem StringBuffer war auch eher allgemein gesprochen - aber gerade bei Systemen mit stark limitierten Resourcen (und dazu zähle ich Smartphones nachwievor), sollte man eben schonend damit umgehen. Und String-Verkettung ist nunmal sehr "teuer" (im Sinne von Speicher und CPU-Last).
 
Was mich jetzt noch verwundert: in dem Falle, daß ich KEINE Daten bekomme, brauch der Befehl if (c.moveToFirst()) { ... } stramme 4 Sekunden. Das kann doch nicht sein, oder?
 
wäre irgendwie komisch

aber frag halt vorher ab ob daten vorhanden sind. ...getCount()
 
Lädst Du eigentlich ganze Table-Objects in Deine Liste, oder füllst Du sie mit abgespeckten Objekten bestehend aus Id und Anzeigestring?

Das ist vielleicht auch noch ein Ansatzpunkt.
 
Nachdem ich gesehen hatte, daß in der DB noch ein paar Indexe auf Suchfeldern gefehlt haben, hat sich die Abfrage incl. Anzeige der Daten auf 3s-5s eingependelt, wenn man in der "Hauptansicht" ist.
Ich denke, das ist zusammen mit einem Progress-Dialog dann schon akzeptabel für den Stresstest, wobei ca. 17.000 Datensätze in der DB vorhanden sind.
Normalerweise befinden sich aber weniger Datensätze auf dem Handy, d.h. die Anwendung ist im Normalfall schneller.

Danke nochmal an alle für die Tips :thumbsup:
 
dafür gibts den danke button :D

gut 3-5 sek für 17000 datensätze ist ganz ok, denk ich
 
  • Danke
Reaktionen: Tom299
ja, im Normalfall sind es wohl eher 1500-2500 Datensätze als Spitzenwerte, im Schnitt weniger als 1000. Das sollte so passen :)
 

Ähnliche Themen

R
Antworten
6
Aufrufe
993
swa00
swa00
M
Antworten
5
Aufrufe
1.076
markusk73
M
Zurück
Oben Unten