Ich weiß, dass SQLite mit extrem großen Datenbankdateien nicht gut funktioniert, selbst wenn sie unterstützt werden (auf der SQLite-Website gab es früher einen Kommentar, der besagt, dass Sie bei Verwendung von Dateigrößen über 1 GB möglicherweise die Verwendung eines Unternehmens-RDBMS in Betracht ziehen sollten finde es nicht mehr, könnte mit einer älteren Version von sqlite zusammenhängen).
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?
database
performance
sqlite
Snazzer
quelle
quelle
Antworten:
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 ganzen Zahlen und 4 Indizes.
Die Idee war, genügend Daten einzufügen, bis die SQLite-Dateien etwa 50 GB groß waren.
Einzelne Tabelle
Ich habe versucht, mehrere Zeilen mit nur einer Tabelle in eine SQLite-Datei einzufügen. Als die Datei ungefähr 7 GB groß war (leider kann ich die Anzahl der Zeilen nicht genau bestimmen), dauerte das Einfügen viel zu lange. Ich hatte geschätzt, dass mein Test zum Einfügen aller meiner Daten 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 haben wird.
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 1-Tabelle wurden auf ~ 700 Tabellen aufgeteilt.
Dieses Setup hatte keine Probleme mit dem Einfügen, es dauerte im Laufe der Zeit 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öschvorgänge durchgeführt werden, desto schlechter wird die Fragmentierung der Datei auf der Festplatte. Daher besteht das Ziel darin, regelmäßig VACUUM zu verwenden, um die Datei zu optimieren und den Dateibereich wiederherzustellen.
Wie aus der Dokumentation hervorgeht , wird jedoch eine vollständige Kopie der Datenbank erstellt, um ein Vakuum zu erzeugen, was sehr lange dauert. Je kleiner die Datenbank ist, desto schneller wird dieser Vorgang abgeschlossen.
Schlussfolgerungen
Für meine spezielle Anwendung werde ich wahrscheinlich Daten auf mehrere Datenbankdateien aufteilen, eine pro Tag, um die Vakuumleistung und 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 Daten im Wert von einem Tag zu löschen (ein üblicher Vorgang für meine Anwendung).
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 das automatische 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 beim automatischen Vakuum nicht der Fall ist. Tatsächlich besagt die Dokumentation, dass dies die Fragmentierung verschlimmern kann, sodass ich regelmäßig ein vollständiges Vakuum für die Datei durchführen muss.
quelle
Wir verwenden DBS von 50 GB + auf unserer Plattform. Keine Beschwerden funktionieren super. Stellen Sie sicher, dass Sie alles richtig machen! Verwenden Sie vordefinierte Anweisungen? * SQLITE 3.7.3
Wenden Sie diese Einstellungen an (direkt nach dem Erstellen der Datenbank).
Hoffe das wird anderen helfen, funktioniert hier super
quelle
PRAGMA main.temp_store = MEMORY;
.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.
Laut der Seite SQLite Limits beträgt die maximale Größe jeder Datenbankseite 32 KB. Und die maximale Anzahl von Seiten in einer Datenbank beträgt 1024 ^ 3. Nach meiner Berechnung ergibt sich also eine maximale Größe von 32 Terabyte. Ich denke, Sie werden die Grenzen Ihres Dateisystems erreichen, bevor Sie SQLites erreichen!
quelle
Der Hauptgrund dafür, dass das Einfügen Ihrer Einfügungen> 48 Stunden dauerte, liegt in Ihren Indizes. Es ist unglaublich schneller zu:
1 - Alle Indizes löschen 2 - Alle Einfügungen durchführen 3 - Indizes erneut erstellen
quelle
Neben der üblichen Empfehlung:
Ich habe aus meinen Erfahrungen mit SQLite3 Folgendes gelernt:
Ändern Sie die Tabelle später nach BedarfSie können mit ALTER TABLE keine Einschränkungen hinzufügen.Frage / Kommentar willkommen. ;-);
quelle
Ich denke, die Hauptbeschwerden über die SQLite-Skalierung sind:
quelle
Ich habe eine 7 GB SQLite-Datenbank. Das Ausführen einer bestimmten Abfrage mit einem inneren Join dauert 2,6 Sekunden. Um dies zu beschleunigen, habe ich versucht, Indizes hinzuzufügen. Je nachdem, welche Indizes ich hinzugefügt habe, ging die Abfrage manchmal auf 0,1 Sekunden und manchmal auf 7 Sekunden zurück. Ich denke, das Problem in meinem Fall war, dass das Hinzufügen eines Index die Leistung beeinträchtigt, wenn eine Spalte stark dupliziert wird :(
quelle
In der SQLite-Dokumentation gab es früher eine Aussage, dass die praktische Größenbeschränkung einer Datenbankdatei einige Dutzend GB: s betrug. Dies lag hauptsächlich daran, dass SQLite bei jedem Start einer Transaktion "eine Bitmap schmutziger Seiten zuweisen" musste. Somit waren 256 Byte RAM für jedes MB in der Datenbank erforderlich. Das Einfügen in eine 50-GB-DB-Datei würde kräftige (2 ^ 8) * (2 ^ 10) = 2 ^ 18 = 256 MB RAM erfordern.
Ab den neuesten Versionen von SQLite wird dies jedoch nicht mehr benötigt. Lesen Sie hier mehr .
quelle
2^18
tatsächlich sind es nur 256 K.Bei der Verwendung des Befehls vakuum sind Probleme mit großen SQLite-Dateien aufgetreten.
Ich habe die Funktion auto_vacuum noch nicht ausprobiert. Wenn Sie erwarten, dass Daten häufig aktualisiert und gelöscht werden, ist dies einen Blick wert.
quelle