Verwenden lange Namen für JSONB-Schlüssel mehr Speicherplatz?

7

Betrachten Sie das Beispiel: Zwei Tabellen foound barjeweils mit einer jsonb-Spalte.

  • Denn fooes gibt eine Million Zeilen, in denen der Wert des jsonb ist [{"a":123}].

  • Denn bares gibt eine Million Zeilen, in denen der Wert des jsonb ist[{"very_long_key_not_premature_optimization_at_all":123}]

Die json-Eingabe barist 46 Zeichen länger als die Eingabe foo. Wäre die Größe von bar46 Millionen Bytes größer als foo?

dvtan
quelle

Antworten:

9

Ja, die Schlüssellänge ist wichtig

Je größer der Schlüssel, desto mehr Platz zum Aufbewahren. JSONB macht nichts Besonderes mit Schlüsseln.

Test Cast

Beispieldaten

# CREATE TABLE foo AS SELECT '{"f":true}'::jsonb FROM generate_series(1,1e6);
SELECT 1000000

# CREATE TABLE bar AS SELECT '{"very_long_key_not_premature_optimization_at_all":true}'::jsonb FROM generate_series(1,1e6);
SELECT 1000000

Tischgrößen

Schauen Sie sich jetzt die Tabellen an

# \dt+ foo;
                   List of relations
 Schema | Name | Type  |  Owner   | Size  | Description 
--------+------+-------+----------+-------+-------------
 public | foo  | table | ecarroll | 42 MB | 
(1 row)

test=# \dt+ bar;
                   List of relations
 Schema | Name | Type  |  Owner   | Size  | Description 
--------+------+-------+----------+-------+-------------
 public | bar  | table | ecarroll | 89 MB | 
(1 row)

Quellcode

Sie können es in der Quelle hier sehen

str = TextDatumGetCString(in_datums[i * 2 + 1]);
len = strlen(str);

v.type = jbvString;

v.val.string.len = len;

ZSON-Erweiterung

Sie können die ZSON-Erweiterung ausprobieren, die eine zeilenübergreifende JSONB-Wörterbuchkomprimierung bietet

ZSON ist eine PostgreSQL-Erweiterung für die transparente JSONB-Komprimierung. Die Komprimierung basiert auf einem gemeinsam genutzten Wörterbuch mit Zeichenfolgen, die in bestimmten JSONB-Dokumenten am häufigsten verwendet werden (nicht nur Schlüssel, sondern auch Werte, Array-Elemente usw.).

In einigen Fällen kann ZSON die Hälfte Ihres Speicherplatzes einsparen und Ihnen etwa 10% mehr TPS geben. Speicher wird ebenfalls gespeichert. Siehe docs / Benchmark.md. Alles hängt jedoch von Ihren Daten und Ihrer Arbeitslast ab. Glauben Sie keinen Benchmarks, überprüfen Sie alles auf Ihre Daten, Konfiguration, Hardware, Workload und PostgreSQL-Version.

Evan Carroll
quelle
1
Gibt es vor diesem Hintergrund eine Praxis zum Minimieren von Jsonb-Schlüsselnamen (ähnlich wie bei Javascript-Minifierern)?
dvtan
1
Nein, sie sind sowieso geröstet, damit sie nicht in der Tabelle stehen. Wen interessiert der Raum? Ich würde nicht vorschlagen, dass Sie den Schlüssel indizieren. Die Indizierung des Werts ist manchmal sinnvoll, aber auch hier sollte die Schlüssellänge keine Rolle spielen. Der Index verknüpft den Wert normalerweise mit dem Speicherort auf der Festplatte. Ich mache keine dummen langen Schlüsselnamen, aber ich kürze sie auch nicht ab, um ein paar MB auf der Festplatte zu sparen. Ich habe eine Million Zeilen erstellt und 27 MB an Schlüssellänge gespart. Das ist meine Zeit nicht wert, sich Sorgen zu machen.
Evan Carroll
1
Ich bin damit einverstanden, dass Speicherplatz billig ist, aber würde er nicht auch Speicher verschwenden? Und nur zur Verdeutlichung: Werden alle JSONB-Spalten geröstet (dh separat auf der Festplatte gespeichert), auch wenn sie nicht> 8 KB sind?
dvtan
der Wert selbst muss nur 2kb sein, afaik. Die Seite muss kleiner als 8 KB sein. (~ 2 Block liest auf einer modernen Festplatte).
Evan Carroll
1
@ DavidTan wurde ebenfalls mit Erwähnung von ZSON aktualisiert.
Evan Carroll