15 Punkte von GN⁺ 2024-07-28 | 4 Kommentare | Auf WhatsApp teilen
  • SQLite kann kleine Blobs (z. B. Vorschaubilder) beim Lesen und Schreiben um 35 % schneller verarbeiten, als wenn sie als einzelne Dateien mit fread() oder fwrite() gelesen oder geschrieben werden
  • Eine einzelne SQLite-Datenbank, die 10-KB-Blobs speichert, benötigt außerdem etwa 20 % weniger Speicherplatz als die Speicherung der Blobs als einzelne Dateien
  • Der Leistungsunterschied scheint daher zu kommen, dass bei der Arbeit mit einer SQLite-Datenbank die Systemaufrufe open() und close() nur einmal erfolgen, während bei einzelnen Blob-Dateien für jeden Blob jeweils einmal open() und close() aufgerufen werden. Der Overhead von open() und close() scheint größer zu sein als der Overhead der Datenbanknutzung
  • Die Größenreduktion entsteht dadurch, dass einzelne Dateien auf das nächste Vielfache der Blockgröße des Dateisystems aufgefüllt werden, während Blobs in einer SQLite-Datenbank dichter gepackt werden

Hinweise

  • Die Zahl von 35 % ist ein grober Richtwert. Die tatsächlichen Messzeiten hängen von Hardware, Betriebssystem und Versuchsdetails ab, außerdem gibt es auf echter Hardware zufällige Leistungsschwankungen
  • Der Wert von 35 % stammt aus Tests auf allen Systemen, die dem Autor leicht zugänglich waren. Einige Reviewer berichteten jedoch, dass SQLite auf ihren Systemen eine höhere Latenz als direktes I/O habe. Der Unterschied ist noch nicht verstanden
  • SQLite zeigte sich bei Experimenten mit kaltem Dateisystem-Cache als nicht so leistungsfähig wie direktes I/O
  • Dieses Dokument widerlegt die verbreitete Annahme, dass relationale Datenbanken langsamer sein müssten als direktes Dateisystem-I/O
  • Laut einer Studie aus dem Jahr 2022 war SQLite in realen Workloads gegenüber Linux Btrfs und Ext4 ungefähr doppelt so schnell

Messmethode

  • Die I/O-Leistung wurde mit dem Programm kvtest.c aus dem SQLite-Quellbaum gemessen
  • Um dieses Testprogramm zu kompilieren, sammelt man die Quelldatei kvtest.c zusammen mit den SQLite-Amalgamation-Quelldateien sqlite3.c und sqlite3.h in einem Verzeichnis und führt dann unter Unix einen Befehl ähnlich dem folgenden aus
  • Das daraus entstehende Programm kvtest erzeugt eine Testdatenbank mit 100.000 zufälligen, unkomprimierten Blobs, wobei jeder Blob zwischen 8.000 und 12.000 Byte groß ist
  • Um Kopien aller Blobs als einzelne Dateien in einem Verzeichnis anzulegen, kann man den Befehl export mit der Kommandozeilenoption --tree ausführen
  • Um die Leistung beim Lesen von Blobs aus der Datenbank und aus einzelnen Dateien zu messen, werden die folgenden Befehle verwendet
  • Mit der Option --blob-api kann SQLite den Blob-Inhalt über die Funktion sqlite3_blob_read() laden, statt SQL-Anweisungen auszuführen, was den Lesetest etwas schneller macht

Messung der Leseleistung

  • Unter Windows10 kann aus einer SQLite-Datenbank etwa 5-mal schneller gelesen werden als durch direktes Lesen der Inhalte von der Festplatte
  • Unter Android ist SQLite beim Lesen etwa 35 % schneller als die Festplatte
  • Beim Lesen aus einer speicherabgebildeten Datenbank mit sqlite3_blob_read() ist SQLite auf Mac und Android 2-mal schneller als das Lesen einzelner Dateien von der Festplatte und unter Windows 10-mal schneller

Messung der Schreibleistung

  • Auf allen Systemen ist die Schreibleistung sowohl bei direktem I/O als auch bei SQLite 5- bis 15-mal langsamer als die Leseleistung
  • Im Schreibtest hat Antivirensoftware praktisch keinen Einfluss auf SQLite-Schreibvorgänge, während direktes Schreiben auf die Festplatte etwa 10-mal langsamer wird
  • Das liegt vermutlich daran, dass SQLite nur eine einzelne Datenbankdatei verändert, während direkte Änderungen auf der Festplatte Tausende einzelner Dateien betreffen, die von der Antivirensoftware geprüft werden müssen

Allgemeine Ergebnisse

  • SQLite ist beim Lesen und Schreiben von Blobs, die in separaten Dateien auf der Festplatte gespeichert sind, konkurrenzfähig und meist schneller
  • SQLite ist unter Windows bei aktivem Antivirenschutz viel schneller als direktes Schreiben auf die Festplatte
  • Lesen ist auf allen Systemen und sowohl bei SQLite als auch bei direktem Festplatten-I/O etwa 10-mal schneller als Schreiben
  • Die I/O-Leistung variiert stark je nach Betriebssystem und Hardware. Vor Schlussfolgerungen sind eigene Messungen nötig
  • Einige andere SQL-Datenbank-Engines raten Entwicklern, Blobs als separate Dateien zu speichern und nur die Dateinamen in der Datenbank abzulegen. In diesem Fall bietet das Speichern des gesamten Blobs in der Datenbank mit SQLite deutlich schnellere Lese- und Schreibvorgänge

Meinung von GN⁺

  • Es ist sehr interessant, dass SQLite beim Lesen und Schreiben eine bessere Leistung zeigt als einzelne Dateien. Das dürfte helfen, die Performance von Anwendungen zu verbessern, die Datenbanken verwenden
  • Allerdings lassen sich diese Benchmark-Ergebnisse nicht pauschal auf alle Situationen übertragen. Sie können je nach Datencharakteristik, Zugriffsmuster und Hardwarekonfiguration variieren. Für wichtige Anwendungen ist es entscheidend, Benchmarks mit realen Workloads durchzuführen
  • Außerdem hat SQLite den Vorteil, Antivirenprüfungen umgehen zu können. Das dürfte besonders für Anwendungen nützlich sein, die mit großen Mengen kleiner Dateien arbeiten
  • Ein Nachteil von SQLite ist, dass alle Daten in einer einzigen Datei gespeichert werden. Wird die Datenbankdatei beschädigt, können sämtliche Daten verloren gehen. Deshalb ist es wichtig, die Datenbankdatei regelmäßig zu sichern

4 Kommentare

 
iolothebard 2024-07-28

Entweder müsste man in die Datenbank auch den Zugriff auf Dateiattribute (Dateiname, Größe, Zugriffsrechte, …) einbeziehen,
oder man müsste statt mit Datei-I/O eher mit Block-I/O vergleichen, oder? …
Wie auch immer, SQLite ist auf jeden Fall schnell.

 
GN⁺ 2024-07-28
Hacker-News-Kommentare
  • Da es keine Dateisystem-Attribute oder Metadaten gibt, sind keine zusätzlichen Attribut-Schreibvorgänge oder Updates nötig, und da Prüfungen auf physische Dateien, Pipes/Symbolic Links, Berechtigungen oder Fehlanpassungen bei der Blockgrößenausrichtung entfallen, ist nur ein einzelner open-Aufruf erforderlich

    • Das ist nachvollziehbar, wenn man Funktionalität weglässt und ein universelles Design ignoriert
    • Wenn man ein FUSE-Mapping für SQLite verwendet und ein Verzeichnis zum Zugriff mountet, kann die Leistung ähnlich oder sogar schlechter sein
    • Wenn man Attribute deaktiviert und ein benutzerdefiniertes Dateisystem mit optimierter Blockgröße erstellt, kann man eine ähnliche Leistung erreichen
    • Es gibt die Einfachheit, Dateien mit Shell-Befehlen wie rsync zu durchsuchen und zu bearbeiten
    • SQLite eignet sich gut für paketierte statische Assets oder Appliance-artige Anwendungen
  • Der vierfache Geschwindigkeitszuwachs unter Windows 10 unterstreicht, wie langsam Windows-Dateisystemaufrufe sind

  • Jemand hatte die Idee, alle von einem Digitalpiano erzeugten Noten in Echtzeit zu protokollieren

    • Mit SQLite wurde das als einzelne Tabelle gespeichert, in der jede Zeile ein MIDI-Ereignis des Pianos ist
    • Die Performance ist gut und die Daten können später analysiert werden
  • Es war interessant, Forschung aus Datenbanklaboren mit OS-Forschung zu vergleichen

    • Relationale Datenbanken sind für kleine einzelne Datensätze und Konsistenz optimiert
    • Mit zunehmender Zeilengröße bricht die Leistung stark ein
  • Es wird erwogen, im WAL2-Modus an eine SQLite-DB anzuhängen

    • Es gibt nahezu keinen Nachteil bei der Schreibleistung und große Vorteile beim Lesen bzw. bei der Analyse
  • In einer SQLite-Datenbank werden die Systemaufrufe open() und close() nur jeweils einmal aufgerufen

    • Das verursacht weniger Overhead als die Verwendung von Blobs in einzelnen Dateien
  • Das Speichern von Dateien mit SQLite-BLOB-Feldern wird nicht empfohlen

    • Die maximale BLOB-Größe beträgt 2 GB
    • Objekte müssen in Bytes serialisiert/deserialisiert werden
    • Für die Interaktion mit anderen Systemen/Diensten werden Dateien benötigt
    • SQLite hat zwar Konfigurationen zur Verarbeitung paralleler Anfragen, aber konkurrierende Anfragen führen dazu, dass die Datenbank gesperrt wird
  • Dass etwas, das auf einem Dateisystem aufbaut, schneller ist als das Dateisystem selbst, bedeutet, dass das Dateisystem bei nicht optimierter Nutzung langsam ist

  • Das Löschen vieler Zeilen in einer SQLite-Datenbank ist langsamer als das Löschen von Dateien

  • Jeder Zugriff auf Dateisysteme/Laufwerke wird vom OS verwaltet

    • Die Datenbankdatei wird in Clustern auf der Festplatte gespeichert
    • Ein Datenbankmanagementsystem wird als praktische Lösung geschaffen, um eine bestimmte Domäne und deren Probleme zu adressieren
 
halfenif 2024-07-28

Vor 20 Jahren wurde eine Architektur, bei der Dateien als BLOBs in einer Oracle-Datenbank abgelegt wurden, gut genutzt … aber ich musste den Leuten jedes Mal ihre Vorteile erklären. Natürlich war das nicht jedes Mal erfolgreich.

 
narusas 2024-07-29

Vor 20 Jahren dürften die Preise für Oracle-SAN-DISKs allerdings nicht gerade niedrig gewesen sein..