it-swarm.com.de

Was sind die Leistungsmerkmale von SQLite bei sehr großen Datenbankdateien?

Ich weiß, dass SQLite mit extrem großen Datenbankdateien auch dann keine gute Leistung erbringt, wenn sie unterstützt werden (auf der SQLite-Website gab es früher einen Kommentar, der besagte, wenn Sie Dateigrößen über 1 GB benötigen, sollten Sie die Verwendung eines Enterprise-Rdbms in Betracht ziehen. Can finde es nicht mehr, könnte mit einer älteren Version von sqlite verwandt sein).

Für meine Zwecke möchte ich jedoch eine Vorstellung davon bekommen, wie schlimm es wirklich ist, bevor ich über andere Lösungen nachdenke.

Ich spreche von SQLite-Datendateien im Multi-Gigabyte-Bereich ab 2 GB. Hat jemand irgendwelche Erfahrungen damit? Irgendwelche Tipps/Ideen?

315
Snazzer

Also habe ich einige Tests mit SQLite für sehr große Dateien durchgeführt und bin zu einigen Schlussfolgerungen gekommen (zumindest für meine spezifische Anwendung).

Die Tests umfassen eine einzelne SQLite-Datei mit entweder einer einzelnen Tabelle oder mehreren Tabellen. Jede Tabelle hatte ungefähr 8 Spalten, fast alle Ganzzahlen und 4 Indizes.

Die Idee war, genügend Daten einzufügen, bis die SQLite-Dateien etwa 50 GB groß sind.

Einzeltabelle

Ich habe versucht, mehrere Zeilen mit nur einer Tabelle in eine SQLite-Datei einzufügen. Bei einer Datei von ca. 7 GB (leider kann ich die Anzahl der Zeilen nicht genau angeben) dauerten die Einfügungen viel zu lange. Ich hatte geschätzt, dass mein Test, um alle meine Daten einzufügen, ungefähr 24 Stunden dauern würde, aber er wurde auch nach 48 Stunden nicht abgeschlossen.

Dies lässt mich zu dem Schluss kommen, dass eine einzelne, sehr große SQLite-Tabelle Probleme mit Einfügungen und wahrscheinlich auch mit anderen Operationen hat.

Ich denke, das ist keine Überraschung, da die Tabelle größer wird und das Einfügen und Aktualisieren aller Indizes länger dauert.

Mehrere Tabellen

Ich habe dann versucht, die Daten nach Zeit auf mehrere Tabellen aufzuteilen, eine Tabelle pro Tag. Die Daten für die ursprüngliche Tabelle 1 wurden in ~ 700 Tabellen aufgeteilt.

Dieses Setup hatte keine Probleme mit dem Einfügen, es dauerte nicht länger, da für jeden Tag eine neue Tabelle erstellt wurde.

Vakuumprobleme

Wie von i_like_caffeine hervorgehoben, ist der Befehl VACUUM ein Problem, je größer die SQLite-Datei ist. Je mehr Einfügungen/Löschungen vorgenommen werden, desto schlechter wird die Fragmentierung der Datei auf der Festplatte. Daher ist es das Ziel, regelmäßig VACUUM zu verwenden, um die Datei zu optimieren und den Dateibereich wiederherzustellen.

Wie in documentation angegeben, wird jedoch eine vollständige Kopie der Datenbank erstellt, um ein Vakuum zu erzeugen, was sehr viel Zeit in Anspruch nimmt. Je kleiner die Datenbank ist, desto schneller wird dieser Vorgang abgeschlossen.

Schlussfolgerungen

Für meine spezielle Anwendung werde ich wahrscheinlich Daten auf mehrere DB-Dateien aufteilen, eine pro Tag, um sowohl die Vakuumleistung als auch die Einfüge-/Löschgeschwindigkeit optimal zu nutzen.

Dies erschwert Abfragen, aber für mich ist es ein lohnender Kompromiss, so viele Daten indizieren zu können. Ein zusätzlicher Vorteil ist, dass ich einfach eine ganze Datenbankdatei löschen kann, um die Daten eines Tages zu löschen (eine für meine Anwendung übliche Operation).

Ich müsste wahrscheinlich auch die Tabellengröße pro Datei überwachen, um zu sehen, wann die Geschwindigkeit zum Problem wird.

Es ist schade, dass es keine andere inkrementelle Vakuummethode als automatisches Vakuum zu geben scheint. Ich kann es nicht verwenden, da mein Ziel für Vakuum darin besteht, die Datei zu defragmentieren (Dateibereich ist keine große Sache), was bei der automatischen Vakuumfunktion nicht der Fall ist. In der Tat heißt es in der Dokumentation, dass die Fragmentierung möglicherweise noch schlimmer wird, sodass ich regelmäßig ein vollständiges Vakuum für die Datei erstellen muss.

235
Snazzer

Wir verwenden DBS von 50 GB + auf unserer Plattform. Keine Beschwerden klappt prima. Stellen Sie sicher, dass Sie alles richtig machen! Verwenden Sie vordefinierte Anweisungen? * SQLITE 3.7.3

  1. Transaktionen
  2. Vorab getroffene Aussagen
  3. Übernehmen Sie diese Einstellungen (direkt nach dem Erstellen der Datenbank)

    PRAGMA main.page_size = 4096;
    PRAGMA main.cache_size=10000;
    PRAGMA main.locking_mode=EXCLUSIVE;
    PRAGMA main.synchronous=NORMAL;
    PRAGMA main.journal_mode=WAL;
    PRAGMA main.cache_size=5000;
    

Hoffe das wird anderen helfen, funktioniert hier super

156
Alex

Ich habe SQLite-Datenbanken mit einer Größe von bis zu 3,5 GB ohne erkennbare Leistungsprobleme erstellt. Wenn ich mich richtig erinnere, hatte SQLite2 möglicherweise einige niedrigere Grenzwerte, aber ich glaube nicht, dass SQLite3 solche Probleme hat.

Gemäß der Seite SQLite Limits beträgt die maximale Größe jeder Datenbankseite 32 KB. Die maximale Anzahl von Seiten in einer Datenbank beträgt 1024 ^ 3. Also nach meiner Rechnung kommt das auf 32 Terabyte als maximale Größe raus. Ich denke, Sie werden an die Grenzen Ihres Dateisystems stoßen, bevor Sie die von SQLite erreichen!

62
Paul Lefebvre

Der Hauptgrund dafür, dass die Erstellung Ihrer Einfügungen mehr als 48 Stunden in Anspruch nahm, liegt in Ihren Indizes. Es ist unglaublich schneller:

1 - Alle Indizes löschen 2 - Alle Einfügungen ausführen 3 - Indizes erneut erstellen

50
user352992

Neben der üblichen Empfehlung:

  1. Drop-Index für Bulk-Insert.
  2. Batch-Einfügungen/Aktualisierungen in großen Transaktionen.
  3. Optimieren Sie Ihren Puffercache/deaktivieren Sie Journal/w PRAGMAs.
  4. Verwenden Sie eine 64-Bit-Maschine (um viel Cache ™ verwenden zu können).
  5. [hinzugefügt im Juli 2014] Verwenden Sie Common Table Expression (CTE) , anstatt mehrere SQL-Abfragen auszuführen! Benötigt SQLite Version 3.8.3.

Aus meinen Erfahrungen mit SQLite3 habe ich Folgendes gelernt:

  1. Verwenden Sie für die maximale Einfügungsgeschwindigkeit kein Schema mit Spalteneinschränkungen. (Ändern Sie die Tabelle später nach Bedarf Sie können mit ALTER TABLE keine Einschränkungen hinzufügen.
  2. Optimieren Sie Ihr Schema, um das zu speichern, was Sie benötigen. Manchmal bedeutet dies, dass Sie Tabellen aufteilen und/oder Ihre Daten sogar komprimieren/transformieren müssen, bevor Sie sie in die Datenbank einfügen. Ein gutes Beispiel ist das Speichern von IP-Adressen als (lange) ganze Zahlen.
  3. Eine Tabelle pro Datenbankdatei - um Sperrenkonflikte zu minimieren. (Verwenden Sie ATTACH DATABASE , wenn Sie ein einzelnes Verbindungsobjekt haben möchten.
  4. SQLite kann verschiedene Datentypen in derselben Spalte speichern (dynamische Typisierung). Nutzen Sie dies zu Ihrem Vorteil.

Frage/Kommentar willkommen. ;-)

30
Lester Cheung

Ich habe eine 7 GB SQLite-Datenbank. Das Ausführen einer bestimmten Abfrage mit einem Inner Join dauert 2,6 s. Um dies zu beschleunigen, habe ich versucht, Indizes hinzuzufügen. Abhängig von den von mir hinzugefügten Indizes ging die Abfrage manchmal auf 0,1 Sekunden und manchmal sogar auf 7 Sekunden zurück. Ich denke, das Problem in meinem Fall war, dass, wenn eine Spalte stark dupliziert ist, das Hinzufügen eines Index die Leistung beeinträchtigt :(

8
Mike Oxynormas

Ich denke, die Hauptbeschwerden über die SQLite-Skalierung sind:

  1. Einzelprozess schreiben.
  2. Kein Spiegeln.
  3. Keine Replikation.
8
Unknown

Ich habe Probleme mit großen SQLite-Dateien bei der Verwendung des Befehls vacuum.

Ich habe die Funktion auto_vacuum noch nicht ausprobiert. Wenn Sie davon ausgehen, dass Daten häufig aktualisiert und gelöscht werden, ist dies einen Blick wert.

6
eodonohoe