Queries and performance

Use JSONB deliberately

Keep flexible nested data in JSONB without turning every relational value into an opaque document.

8 minute lesson

~~~

jsonb stores parsed JSON and supports operators and indexes for querying inside it.

It works well for optional metadata whose keys genuinely vary:

CREATE TABLE events (
  id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  kind text NOT NULL,
  occurred_at timestamptz NOT NULL,
  metadata jsonb NOT NULL DEFAULT '{}'::jsonb
);

INSERT INTO events (kind, occurred_at, metadata)
VALUES ('purchase', now(), '{"plan":"pro","source":"newsletter"}');

Query a text value with ->>:

SELECT id
FROM events
WHERE metadata ->> 'source' = 'newsletter';

-> returns JSON; ->> returns text. This distinction affects comparisons and indexes. PostgreSQL also supports containment queries such as metadata @> '{"plan":"pro"}'.

A general GIN index can accelerate many containment and key-existence queries:

CREATE INDEX events_metadata_gin_idx
ON events USING gin (metadata);

For one frequent expression, a smaller expression index may be a better fit:

CREATE INDEX events_source_idx
ON events ((metadata ->> 'source'));

Use EXPLAIN ANALYZE with representative data before deciding. The broad GIN index costs more storage and write work, while an expression index serves a narrower query.

Keep ordinary columns for values you routinely filter, join, constrain, sort, or update independently. Hiding customer_id, status, or timestamps inside JSON weakens type checks and foreign keys and makes every query repeat extraction logic. JSONB fits the flexible edge of a relational model, not the entire model by default.

Updates rewrite the JSONB value, so a large document that changes one small key can create unnecessary write amplification. Split frequently updated fields into columns or related tables.

Try it: store two event kinds with different metadata, query them by containment, inspect the plan before and after an index, then decide whether the measured workload justifies keeping it.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →