PostgreSQL: JSONB vs JSON - скрытая причина деградации производительности, которую большинство проектов обнаруживает слишком поздно

mr. Cooper 2 часа назад Веб-разработка
PostgreSQL: JSONB vs JSON - скрытая причина деградации производительности, которую большинство проектов обнаруживает слишком поздно

Разница между json и jsonb в PostgreSQL выглядит незначительной только до момента, когда система начинает работать под реальной нагрузкой. На уровне синтаксиса оба типа делают одно и то же - хранят JSON. Но на уровне архитектуры базы данных они ведут себя принципиально по-разному.

И именно это различие становится причиной того, почему одни системы спокойно масштабируются, а другие начинают “тормозить без причины” после роста данных, даже если код и запросы не менялись.

Что PostgreSQL делает с JSON на самом деле

Когда используется json, база хранит данные как обычный текст. PostgreSQL не понимает структуру заранее и каждый раз при обращении к полям вынужден заново разбирать JSON-строку. Фактически это означает, что структура данных существует только в момент выполнения запроса.

jsonb устроен иначе. При вставке PostgreSQL один раз парсит JSON, нормализует его, убирает лишние элементы и сохраняет уже готовую структуру в бинарном виде. После этого работа идёт не с текстом, а с предобработанным деревом данных, которое можно эффективно индексировать и использовать в запросах.

Это различие не видно в простых CRUD-операциях, но становится критическим, как только JSON начинает участвовать в фильтрации.

Где система начинает вести себя по-разному

На небольших таблицах оба типа выглядят одинаково. Но как только появляется запрос с фильтрацией по вложенному полю, поведение базы расходится.

SELECT *
FROM events
WHERE data->>'event' = 'click';

При использовании json PostgreSQL вынужден проверять каждую строку, потому что у него нет оптимизированного способа доступа к структуре.

С jsonb появляется возможность использовать индекс и уйти от полного сканирования таблицы.

CREATE INDEX idx_events_event
ON events ((data->>'event'));

На этом этапе разница перестаёт быть теоретической. Она напрямую влияет на время ответа API и нагрузку на CPU при росте данных.

Контринсайт, который ломает привычное понимание JSONB

Распространённое упрощение звучит так: jsonb быстрее json.

Но в реальности это утверждение неполное и часто вводит в заблуждение. jsonb ускоряет чтение и поиск, но увеличивает стоимость записи и обновления данных. В системах с высокой частотой записи, где данные редко читаются, эта разница может быть нейтральной или даже негативной.

Это означает, что выбор между json и jsonb - это не выбор “что быстрее”, а выбор между моделями нагрузки. jsonb оптимизирован под чтение и фильтрацию, а json - под минимально обработанное хранение без дополнительной стоимости на вставке.

Почему деградация всегда проявляется позже

JSON почти всегда появляется в проекте как временное решение. Он позволяет быстро запускать функциональность без проектирования схемы данных.

Проблемы начинаются позже, когда система растёт. Появляются фильтры, аналитика, отчёты, выборки по вложенным полям. В этот момент JSON перестаёт быть просто хранилищем и становится частью логики запросов.

Именно здесь возникает скрытая деградация: запросы начинают выполняться медленнее, нагрузка растёт, но причина не очевидна, потому что структура базы формально остаётся валидной.

Реальный сценарий, который повторяется в продакшене

В типичной системе событий пользователей данные сначала хранятся в json:

{"user_id": 42, "event": "click", "page": "/home"}

На старте это удобно: нет миграций, нет схемы, высокая скорость разработки.

Но позже появляются запросы аналитики:

SELECT *
FROM events
WHERE data->>'event' = 'click';

При росте таблицы до миллионов записей PostgreSQL начинает выполнять последовательное сканирование. Это не ошибка запроса - это ограничение выбранной модели хранения.

После перехода на jsonb и добавления индекса поведение системы меняется фундаментально: запросы начинают использовать индекс, и время выполнения перестаёт зависеть от размера таблицы.

ALTER TABLE events
ALTER COLUMN data TYPE JSONB USING data::jsonb;
CREATE INDEX idx_events_event
ON events ((data->>'event'));

Когда JSON всё ещё уместен

json остаётся оправданным только в сценариях, где данные не участвуют в логике обработки. Это может быть хранение сырых webhook-запросов, архивирование внешних API-ответов или логирование, где важна полная сохранность исходного формата без трансформаций и без запросов по внутренним полям.

Как только появляется необходимость поиска, агрегации или индексации, JSON перестаёт быть эффективным инструментом и начинает ограничивать систему.

Архитектурная ошибка, которая встречается чаще всего

Самая частая проблема в реальных проектах заключается не в выборе между json и jsonb, а в попытке использовать JSON как замену нормализованной схемы базы данных.

Когда вся структура данных уходит в JSON-поля, система теряет предсказуемость, усложняется оптимизация запросов, ухудшается использование индексов и растёт стоимость сопровождения.

В таких архитектурах проблема производительности почти никогда не связана с PostgreSQL как системой. Она связана с тем, что база используется вне своей реляционной модели.

Почему JSONB стал стандартом в реальных backend-системах

В большинстве продакшн-систем основная нагрузка приходится не на запись, а на чтение и фильтрацию данных. Именно в этих сценариях jsonb даёт системное преимущество: он позволяет строить индексы, выполнять быстрые выборки и работать с вложенными структурами без полного обхода таблицы.

Дополнительная стоимость вставки компенсируется кратным выигрышем на чтении и масштабировании, особенно при росте данных.

Итог

Разница между json и jsonb - это не вопрос формата хранения и не синтаксическая деталь. Это выбор модели поведения данных внутри системы.

json подходит только для хранения информации без дальнейшей обработки. jsonb - это структурированный формат, рассчитанный на поиск, фильтрацию и масштабирование под нагрузкой.

Именно поэтому в реальных backend-системах выбор почти всегда смещается в сторону jsonb: не потому что он современнее, а потому что он соответствует тому, как данные реально используются в продакшене.

Комментарии

Пока нет комментариев. Будьте первым, кто напишет.

Чтобы оставить комментарий, войдите в аккаунт.

Похожие статьи