13 Punkte von GN⁺ 2023-12-07 | 1 Kommentare | Auf WhatsApp teilen
  • Die bestehenden JSON-Funktionen von SQLite wurden neu geschrieben. Je nach Nutzungsmuster laufen sie um ein Mehrfaches schneller
  • Die ursprünglichen JSON-Funktionen arbeiteten in drei Schritten
    1. JSON wird in ein internes Binärformat geparst, das für C-Code leicht zu verarbeiten ist
    2. Die angeforderte Operation wird ausgeführt, etwa ein bestimmtes Feld zu finden oder JSON zu ändern
    3. Wenn die Operation das JSON verändert hat, wird das interne Binärformat zur Ausgabe oder Speicherung wieder in einen RFC-8279-JSON-String umgewandelt
  • Abgesehen von Schritt 2 sind Schritt 1 und 3 Overhead
  • SQLite verwendete eine interne binäre Form von JSON mit vielen Zeigern. Das passt gut zu C-Programmen, ist aber schwer zu serialisieren
  • Mit der JSONB-Neuschreibung wurde diese interne binäre Darstellung von JSON in ein zusammenhängendes Byte-Array geändert, das sich als SQL-BLOB lesen oder schreiben lässt
  • Dadurch kann die intern verwendete JSON-Darstellung statt als JSON-Text in der Datenbank gespeichert werden, womit der Overhead von Schritt 1 und 3 entfällt

Was sich geändert hat

  • Alle bestehenden Funktionen bleiben vollständig erhalten. Es wurden nur neue Funktionen hinzugefügt
  • Alle JSON-Funktionen, die bisher JSON-Text als Eingabe akzeptieren, akzeptieren nun bei denselben Parametern auch binäre JSONB-Inhalte
    • Es ist nicht nötig anzugeben, ob die Funktion Text oder Binärdaten erhalten soll. Die Funktion erkennt das selbst
  • JSON-Funktionen, die JSON ausgeben, gibt es nun in zwei Versionen
    • Die bisherigen Funktionen mit dem Präfix json_ arbeiten wie zuvor
    • Es gibt Funktionen mit dem Präfix jsonb_, die JSONB statt Text-JSON zurückgeben, sodass bei der normalen Verarbeitung Schritt 3 übersprungen wird
  • Ohne Änderungen an der Anwendung wird alles weiterhin wie bisher funktionieren, nur geringfügig schneller (etwa 1%)
  • Wenn die Anwendung jedoch angepasst wird und statt Text-JSON JSONB speichert, sind zumindest bei JSON-intensiven Aufgaben Leistungssteigerungen um den Faktor 3 möglich
  • Da JSONB in den meisten Fällen außerdem etwas kleiner als Text-JSON ist (etwa 5% bis 10% kleiner), kann sich bei starker JSON-Nutzung auch die Datenbankgröße leicht verringern

1 Kommentare

 
GN⁺ 2023-12-07
Hacker-News-Kommentare
  • Es gibt viel Verwirrung rund um JSONB.

    • JSONB wird in Anwendungen sehr ähnlich wie der JSON-Datentyp verwendet.
    • Anwendungen lesen und schreiben weiterhin JSON-Strings, sehen den eigentlichen JSONB-Inhalt jedoch nicht.
    • Dieselben SQL-Funktionen sind mit dem Präfix jsonb_ verfügbar.
    • Der JSON-Datentyp wird auf der Festplatte als JSON gespeichert, JSONB hingegen in einem speziellen Binärformat.
    • Der JSON-Datentyp muss das gesamte JSON parsen, um Operationen auszuführen, während JSONB den Parsing-Schritt überspringen und direkt auf dem Festplattenformat arbeiten kann.
    • Wenn man in SQLite einfach den gesamten JSON-Blob liest und schreibt, ist der JSON-Datentyp passend; wenn man Daten jedoch per SQL abfragt oder bearbeitet, ist JSONB besser geeignet.
  • JSONB ist ein von Postgres bereitgestelltes Format und wird wegen besserer Leseleistung im Vergleich zu normalem JSON empfohlen.

  • Es hat Jahre gedauert, den Zweck eines Dokumentenspeichers zu verstehen, und er eignet sich hervorragend zum Aufbau eines POC (Proof of Concept).

    • Eine stärkere JSON-Unterstützung wird SQLite dabei helfen, ein geeigneter Dokumentenspeicher zu werden.
    • Wenn Protobuf-Nachrichten serialisiert und deserialisiert werden, erhält man vollständige Typunterstützung, und wenn diese Spalte als JSONB vorliegt, kann man nach dieser Spalte filtern, ohne durchsuchbare Daten in andere Spalten auslagern zu müssen.
  • Neugier auf den Release-Prozess von SQLite.

    • Die aktuelle Release-Version ist 3.44, und JSONB ist in den Pre-Release-Snapshots enthalten.
    • Man möchte diese Funktion in D1 von Cloudflare und bei Fly.io nutzen, aber die SQLite-Versionen wurden möglicherweise nicht veröffentlicht oder sind angepasst.
    • API-Änderungen könnten Cloudflares Versprechen brechen, SQLite-kompatible Dump-/Query-Dateien importieren zu können.
  • JSONB kann in Pre-Release-Snapshots oder im Playground ausprobiert werden.

  • Die Kernidee der JSONB-Spezifikation ist, dass jedes Element mit einem Header beginnt, der Größe und Typ enthält.

    • Es wird vorgeschlagen, dass das Hinzufügen von Größenangaben zur JSON-Spezifikation den für die JSON-Verarbeitung benötigten Speicher reduzieren könnte.
  • Mit BSON von MongoDB ist man vertraut, mit JSONB jedoch nicht.

    • Siehe diesen Blogbeitrag, der die Unterschiede zwischen JSONB und BSON erklärt.
  • JSONB wirkt sich auf die Performance aus.

  • Es wäre wünschenswert, JSON-Daten über mehrere Zeilen hinweg komprimieren zu können.

    • In jeder Zeile liegen sehr ähnliche Blobs vor, und es wird eine Möglichkeit benötigt, den Speicherbedarf vieler ähnlicher Blobs über mehrere Zeilen hinweg zu reduzieren.
  • Trotz des internen Formats ist es in Anwendungen sofort nutzbar.

    • Zum Beispiel gibt es bei Batch-Inserts in Python einen spürbaren Overhead pro Insert-Aufruf und Zeile.
    • JSONB kann die Performance mithilfe von CTEs (Common Table Expressions) verbessern.
    • json_each kann Parameter akzeptieren, die in der Anwendung als JSONB-BLOB gebunden werden.