Мини-гайд по трём ключевым сущностям PostgreSQL: соединения, буфер и WAL
1. Соединения (Connections)
PostgreSQL по умолчанию позволяет одновременно до 100 соединений (
🔹 Проблема: слишком много прямых соединений создают нагрузку на память и CPU.
🔹 Решение: используйте пуллинг через PgBouncer или Pgpool-II.
🔹 Совет: на проде стремитесь держать
2. Буфер (Shared Buffers & Work Mem)
PostgreSQL активно использует память для кэширования страниц и сортировок.
🔹
🔹
🔹 Best practice:
🔹 Установите
🔹 Настройте
3. WAL (Write-Ahead Log)
WAL обеспечивает надёжность и репликацию.
🔹
🔹
🔹 Архивация WAL для резервных копий:
🔹 Рекомендации:
🔹 Увеличьте
🔹 Настройте сжатие WAL (pg_wal) для экономии места.
💡 Сохрани, чтобы не забыть!
А как вы оптимизируете соединения, буфер и WAL в своих проектах?
#db
👉 @database_info
1. Соединения (Connections)
PostgreSQL по умолчанию позволяет одновременно до 100 соединений (
max_connections).🔹 Проблема: слишком много прямых соединений создают нагрузку на память и CPU.
🔹 Решение: используйте пуллинг через PgBouncer или Pgpool-II.
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
pool_mode = transaction
max_client_conn = 500
default_pool_size = 20
🔹 Совет: на проде стремитесь держать
max_connections < 200 и масштабируйте через пуллер.2. Буфер (Shared Buffers & Work Mem)
PostgreSQL активно использует память для кэширования страниц и сортировок.
🔹
shared_buffers – основной буфер кэша:
shared_buffers = 4GB # ≈25% от RAM на выделенном сервере
🔹
work_mem – память на сортировку/слияние одного потока:
work_mem = 64MB # для сложных запросов с сортировками и хэш-джоинами
maintenance_work_mem = 512MB # для VACUUM/CREATE INDEX
🔹 Best practice:
🔹 Установите
shared_buffers ≈ 25% RAM.🔹 Настройте
work_mem исходя из числа параллельных операций, не превышайте общий объём памяти.3. WAL (Write-Ahead Log)
WAL обеспечивает надёжность и репликацию.
🔹
wal_level – детальность логирования:
wal_level = replica # для потоковой репликации
🔹
checkpoint_timeout и max_wal_size:
checkpoint_timeout = 10min
max_wal_size = 1GB
🔹 Архивация WAL для резервных копий:
archive_mode = on
archive_command = 'cp %p /mnt/backup/wal/%f'
🔹 Рекомендации:
🔹 Увеличьте
max_wal_size, если у вас большие всплески нагрузки.🔹 Настройте сжатие WAL (pg_wal) для экономии места.
💡 Сохрани, чтобы не забыть!
А как вы оптимизируете соединения, буфер и WAL в своих проектах?
#db
👉 @database_info
👍11❤2
🎯 Типы баз данных — кратко и по делу
Выбирая базу данных для проекта, важно понимать их ключевые особенности. Ниже — наглядная классификация:
🔷 Реляционные (Relational)
Классика: таблицы со строгими схемами и связями.
📌 ACID, SQL, целостность данных
📌 Идеальны для: финансов, e-commerce, CRM, ERP, банков и инвентаризации
🔷 Документные (Document)
Гибкие NoSQL-базы на основе JSON-документов
📌 Горизонтальное масштабирование, вложенные структуры
📌 Подходят для: CMS, каталогов, мобильных и веб-приложений
🔷 In-Memory
Хранят данные в оперативной памяти — максимум скорости
📌 Используются как кэш, для сессий, real-time аналитики
📌 Примеры: Redis, Memcached
🔷 Графовые (Graph)
Работают с узлами и связями — мощные запросы по связности
📌 Идеальны для соцсетей, рекомендаций, мошеннических схем
📌 Пример: Neo4j
🔷 Временные (Time-Series)
Оптимизированы под работу с временными метками
📌 Подходят для метрик, IoT, логов, финансовых данных
📌 Примеры: InfluxDB, TimescaleDB
🔷 Пространственные (Spatial)
Работают с геоданными и координатами
📌 Используются в GIS, логистике, экологии, городском планировании
🔷 Колончатые (Columnar)
Хранят данные по колонкам — супер для аналитики
📌 Быстрые агрегации, параллельная обработка
📌 Используются в BI, отчетах, хранилищах данных
📌 Пример: ClickHouse
🔷 Ключ-Значение (Key-Value)
Простые NoSQL-базы — пара ключ-значение
📌 Идеальны для кэшей, предпочтений, сессий
📌 Примеры: Redis, DynamoDB
🔍 Правильный выбор базы — залог производительности и масштабируемости проекта.
#db
👉 @database_info
Выбирая базу данных для проекта, важно понимать их ключевые особенности. Ниже — наглядная классификация:
🔷 Реляционные (Relational)
Классика: таблицы со строгими схемами и связями.
📌 ACID, SQL, целостность данных
📌 Идеальны для: финансов, e-commerce, CRM, ERP, банков и инвентаризации
🔷 Документные (Document)
Гибкие NoSQL-базы на основе JSON-документов
📌 Горизонтальное масштабирование, вложенные структуры
📌 Подходят для: CMS, каталогов, мобильных и веб-приложений
🔷 In-Memory
Хранят данные в оперативной памяти — максимум скорости
📌 Используются как кэш, для сессий, real-time аналитики
📌 Примеры: Redis, Memcached
🔷 Графовые (Graph)
Работают с узлами и связями — мощные запросы по связности
📌 Идеальны для соцсетей, рекомендаций, мошеннических схем
📌 Пример: Neo4j
🔷 Временные (Time-Series)
Оптимизированы под работу с временными метками
📌 Подходят для метрик, IoT, логов, финансовых данных
📌 Примеры: InfluxDB, TimescaleDB
🔷 Пространственные (Spatial)
Работают с геоданными и координатами
📌 Используются в GIS, логистике, экологии, городском планировании
🔷 Колончатые (Columnar)
Хранят данные по колонкам — супер для аналитики
📌 Быстрые агрегации, параллельная обработка
📌 Используются в BI, отчетах, хранилищах данных
📌 Пример: ClickHouse
🔷 Ключ-Значение (Key-Value)
Простые NoSQL-базы — пара ключ-значение
📌 Идеальны для кэшей, предпочтений, сессий
📌 Примеры: Redis, DynamoDB
🔍 Правильный выбор базы — залог производительности и масштабируемости проекта.
#db
👉 @database_info
❤13👍5👎1
📕 Управление ресурсами в ClickHouse для разработчиков, администраторов баз данных, инженеров и аналитиков данных
На открытом уроке 17 июня в 20:00 мск мы разберем тонкости управления ресурсами и профилирования запросов в ClickHouse:
📗 На вебинаре разберём:
1. Методы управления ресурсами в ClickHouse: настройка квот, ограничений и профилей пользователей;
2. Детальное профилирование запросов для выявления узких мест и оптимизации их выполнения;
📘 В результате на практике разберете важные аспекты для обеспечения высокой производительности и стабильности работы системы в ClickHouse.
👉 Регистрация и подробности о курсе ClickHouse для инженеров и архитекторов БД: https://vk.cc/cMSOpO
Все участники открытого урока получат скидку на курс "ClickHouse для инженеров и архитекторов БД"
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
На открытом уроке 17 июня в 20:00 мск мы разберем тонкости управления ресурсами и профилирования запросов в ClickHouse:
📗 На вебинаре разберём:
1. Методы управления ресурсами в ClickHouse: настройка квот, ограничений и профилей пользователей;
2. Детальное профилирование запросов для выявления узких мест и оптимизации их выполнения;
📘 В результате на практике разберете важные аспекты для обеспечения высокой производительности и стабильности работы системы в ClickHouse.
👉 Регистрация и подробности о курсе ClickHouse для инженеров и архитекторов БД: https://vk.cc/cMSOpO
Все участники открытого урока получат скидку на курс "ClickHouse для инженеров и архитекторов БД"
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
👍4
Мини-гайд: VACUUM в PostgreSQL — когда, зачем и как?
PostgreSQL не удаляет строки сразу при
⠀
💡 VACUUM — инструмент для уборки "мусора" и поддержания БД в форме.
Варианты:
Когда запускать вручную?
– Если
– После больших батчевых удалений/обновлений.
– Перед бэкапом (особенно
⠀
Пример:
Лайфхаки:
Не злоупотребляй
Настрой
Следи за bloating:
👉 VACUUM — не уборка по графику, а гигиена твоей БД. Запустишь вовремя — не будет проблем с производительностью.
Сохрани, чтобы не забыть 💾
#db
👉 @database_info
PostgreSQL не удаляет строки сразу при
DELETE или UPDATE. Вместо этого они помечаются как "мертвые", а данные продолжают занимать место. Со временем таблицы раздуваются, индексы тормозят, запросы тянут ресурсы.⠀
💡 VACUUM — инструмент для уборки "мусора" и поддержания БД в форме.
Варианты:
VACUUM — убирает мусор, но не возвращает место ОС.VACUUM FULL — перезаписывает таблицу и реально освобождает диск (но блокирует таблицу!).ANALYZE — обновляет статистику планировщика запросов.VACUUM ANALYZE — два в одном: чистка + статистика.Когда запускать вручную?
– Если
autovacuum не справляется (часто видно по pg_stat_user_tables).– После больших батчевых удалений/обновлений.
– Перед бэкапом (особенно
VACUUM FULL для экономии места).⠀
Пример:
VACUUM VERBOSE my_table;
VACUUM FULL my_table;
Лайфхаки:
Не злоупотребляй
FULL — он тяжёлый.Настрой
autovacuum под нагрузки: autovacuum_vacuum_threshold, autovacuum_vacuum_scale_factor и т.д.Следи за bloating:
pgstattuple и pg_bloat_check.👉 VACUUM — не уборка по графику, а гигиена твоей БД. Запустишь вовремя — не будет проблем с производительностью.
Сохрани, чтобы не забыть 💾
#db
👉 @database_info
👍17❤3
Антипаттерн: значения по умолчанию
Кажется безобидным: "Ну не знаю я сейчас значение — пусть будет
– Джоины начинают возвращать меньше строк, чем ты ожидал.
–
–
–
🧱 В чем корень проблемы?
По умолчанию большинство СУБД позволяют
📌 Как избежать?
1. Всегда указывай
2. Думай, нужен ли
3. Добавляй ограничения (
4. Следи за миграциями — новые поля по умолчанию тоже могут быть
✅ Вывод:
Проектируя схему, подходи к
Сохрани, чтобы не зарываться в
#db
👉 @database_info
NULL везде, где можноКажется безобидным: "Ну не знаю я сейчас значение — пусть будет
NULL". Но потом:– Джоины начинают возвращать меньше строк, чем ты ожидал.
–
WHERE column = 'X' не находит ничего, потому что там NULL.–
COUNT(column) искажает статистику.–
IS NULL и COALESCE() плодятся по всему коду.🧱 В чем корень проблемы?
По умолчанию большинство СУБД позволяют
NULL, если явно не указано NOT NULL. Это приводит к схеме, где половина полей может быть «ничем», хотя такого смысла в данных нет.📌 Как избежать?
1. Всегда указывай
NOT NULL, если поле обязательно.2. Думай, нужен ли
NULL вообще. Иногда лучше завести отдельный флаг или значение по умолчанию (например, '' или 0).3. Добавляй ограничения (
CHECK), если значение должно быть в определённом диапазоне.4. Следи за миграциями — новые поля по умолчанию тоже могут быть
NULL.✅ Вывод:
Проектируя схему, подходи к
NULL осознанно. Это не просто "ничего" — это потенциальная боль при запросах и анализе.Сохрани, чтобы не зарываться в
NULL -хаос спустя полгода разработки!#db
👉 @database_info
👍14❤2
Хотите попасть в аналитику, но теряетесь в море информации и не понимаете, какие навыки действительно важны? Боитесь, что без опыта вас не возьмут на работу? И да, ещё один популярный вопрос — а что, если мне 30/40/50+ лет?
Андрон Алексанян — эксперт по аналитике с 8 летним опытом и по совместительству CEO Simulative — покажет рабочие схемы и четкий план, как устроиться в аналитику быстрее, даже если у вас нет опыта.
Что будет на вебинаре?
— Покажем реальные примеры, как оформить резюме и портфолио, чтобы привлекать внимание;
— Обсудим какие отклики работают, а какие сразу отправляют в корзину;
— Изнанка найма: инсайдерский взгляд на процессы отбора
🕗 Важно досмотреть вебинар до конца, чтобы получить бонус от нас, который поможет бустануть карьеру.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Какой тип индекса выбрать в PostgreSQL?
Индексы — мощный инструмент для ускорения запросов, но не все они одинаково полезны. В PostgreSQL есть несколько типов индексов, и вот как не промахнуться с выбором:
🔹 B-tree (по умолчанию)
📌 Лучший выбор для:
✅ Поддерживает сортировку.
💡 Используется в 90% случаев.
🔹 Hash
📌 Только для точного сравнения
🚫 Не поддерживает диапазоны, сортировку,
⚠️ Редко используется, но может быть быстрее B-tree на
🔹 GIN (Generalized Inverted Index)
📌 Для массивов,
💡 Отличен при поиске по вложенным структурам или множеству значений.
🔹 GiST (Generalized Search Tree)
📌 Для геоданных (PostGIS), поиска по диапазонам,
💡 Более универсален, но медленнее в некоторых кейсах, чем GIN.
🔹 BRIN (Block Range Index)
📌 Для огромных таблиц, где данные физически упорядочены.
💡 Занимает очень мало места.
⚠️ Не всегда эффективен — зависит от корреляции данных.
✅ Не кидайтесь ставить индекс "на всякий случай". Подбирай тип под паттерн запроса и тип данных.
#db
👉 @database_info
Индексы — мощный инструмент для ускорения запросов, но не все они одинаково полезны. В PostgreSQL есть несколько типов индексов, и вот как не промахнуться с выбором:
🔹 B-tree (по умолчанию)
📌 Лучший выбор для:
=, <, >, BETWEEN, ORDER BY.✅ Поддерживает сортировку.
💡 Используется в 90% случаев.
CREATE INDEX idx_users_name ON users(name);
🔹 Hash
📌 Только для точного сравнения
=.🚫 Не поддерживает диапазоны, сортировку,
LIKE.⚠️ Редко используется, но может быть быстрее B-tree на
=.
CREATE INDEX idx_users_email_hash ON users USING hash(email);
🔹 GIN (Generalized Inverted Index)
📌 Для массивов,
jsonb, full-text search.💡 Отличен при поиске по вложенным структурам или множеству значений.
CREATE INDEX idx_data_tags ON posts USING gin(tags);
🔹 GiST (Generalized Search Tree)
📌 Для геоданных (PostGIS), поиска по диапазонам,
tsvector.💡 Более универсален, но медленнее в некоторых кейсах, чем GIN.
CREATE INDEX idx_events_location ON events USING gist(location);
🔹 BRIN (Block Range Index)
📌 Для огромных таблиц, где данные физически упорядочены.
💡 Занимает очень мало места.
⚠️ Не всегда эффективен — зависит от корреляции данных.
CREATE INDEX idx_logs_timestamp ON logs USING brin(timestamp);
✅ Не кидайтесь ставить индекс "на всякий случай". Подбирай тип под паттерн запроса и тип данных.
#db
👉 @database_info
2🔥8👍3👏3❤2
SQL vs NoSQL: что выбрать для реального проекта?
Один из самых частых вопросов:
«Нам вообще SQL нужен? Может, сразу MongoDB?»
Разберёмся коротко и по делу 👇
🔷 SQL (PostgreSQL, MySQL, etc.)
Плюсы:
– Строгая схема → меньше ошибок на проде
– Сложные запросы (JOIN, агрегаты) — легко
– ACID-гарантии → важно для денег, заказов, логистики
– Большое комьюнити, mature-тулинги, репликация, индексы
Когда выбирать:
✅ Чёткая структура данных
✅ Много взаимосвязей (нормализация)
✅ Сложные аналитические выборки
✅ Транзакции критичны
🔶 NoSQL (MongoDB, Redis, DynamoDB, etc.)
Плюсы:
– Гибкая схема (можно быстро пихать JSON как есть)
– Горизонтальное масштабирование — встроено
– Подходит для high-load, real-time, event-based систем
Когда выбирать:
✅ Частые изменения структуры данных
✅ Скорость важнее связности
✅ Огромные объёмы с минимальными связями
✅ Event storage, логирование, IoT, временные данные
❗️Частые ошибки:
– "Берём Mongo, потому что модно" — а потом страдаем с джоинами руками
– "Только SQL, потому что так всегда делали" — и не справляемся с масштабом
🔧Часто лучший вариант — гибрид.
Например:
– PostgreSQL → для core бизнес-логики
– Redis → для кеша
– MongoDB → для логов или гибких анкет
Вывод:
Никто не лучше сам по себе. Всё зависит от данных и задач.
А ты чем пользуешься чаще — SQL или NoSQL?
Поделись с командой, если на старте нового проекта 🧠
#db
👉 @database_info
Один из самых частых вопросов:
«Нам вообще SQL нужен? Может, сразу MongoDB?»
Разберёмся коротко и по делу 👇
🔷 SQL (PostgreSQL, MySQL, etc.)
Плюсы:
– Строгая схема → меньше ошибок на проде
– Сложные запросы (JOIN, агрегаты) — легко
– ACID-гарантии → важно для денег, заказов, логистики
– Большое комьюнити, mature-тулинги, репликация, индексы
Когда выбирать:
✅ Чёткая структура данных
✅ Много взаимосвязей (нормализация)
✅ Сложные аналитические выборки
✅ Транзакции критичны
🔶 NoSQL (MongoDB, Redis, DynamoDB, etc.)
Плюсы:
– Гибкая схема (можно быстро пихать JSON как есть)
– Горизонтальное масштабирование — встроено
– Подходит для high-load, real-time, event-based систем
Когда выбирать:
✅ Частые изменения структуры данных
✅ Скорость важнее связности
✅ Огромные объёмы с минимальными связями
✅ Event storage, логирование, IoT, временные данные
❗️Частые ошибки:
– "Берём Mongo, потому что модно" — а потом страдаем с джоинами руками
– "Только SQL, потому что так всегда делали" — и не справляемся с масштабом
🔧Часто лучший вариант — гибрид.
Например:
– PostgreSQL → для core бизнес-логики
– Redis → для кеша
– MongoDB → для логов или гибких анкет
Вывод:
Никто не лучше сам по себе. Всё зависит от данных и задач.
А ты чем пользуешься чаще — SQL или NoSQL?
Поделись с командой, если на старте нового проекта 🧠
#db
👉 @database_info
👍12❤1
📕 Архитектура и дизайн систем на основе NoSQL в облаках для разработчиков, администраторов, специалистов по базам данных, Data engineers, Backend и FullStack-разработчиков
На открытом уроке 10 июля в 20:00 мск мы погрузимся в тонкости работы с системами на основе NoSQL в облачных средах:
📗 На вебинаре разберём:
1. Основы NoSQL и его применение в облачных средах;
2. Реальные примеры и кейсы использования NoSQL в облаках;
📘 В результате на практике разберетесь в настройке и развертывании NoSQL баз данных в популярных облачных платформах (Сберклауд, Яндекс Облако, AWS, Google Cloud, Azure) и освоите применение основных операции с данными, масштабирования и управления производительностью NoSQL.
👉 Регистрация и подробности о курсе NoSQL: https://vk.cc/cNsUyb
Все участники открытого урока получат скидку на курс "NoSQL"
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
На открытом уроке 10 июля в 20:00 мск мы погрузимся в тонкости работы с системами на основе NoSQL в облачных средах:
📗 На вебинаре разберём:
1. Основы NoSQL и его применение в облачных средах;
2. Реальные примеры и кейсы использования NoSQL в облаках;
📘 В результате на практике разберетесь в настройке и развертывании NoSQL баз данных в популярных облачных платформах (Сберклауд, Яндекс Облако, AWS, Google Cloud, Azure) и освоите применение основных операции с данными, масштабирования и управления производительностью NoSQL.
👉 Регистрация и подробности о курсе NoSQL: https://vk.cc/cNsUyb
Все участники открытого урока получат скидку на курс "NoSQL"
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
❌ Антипаттерн: UUID как PK без учёта последствий
Выглядит красиво: глобально уникальный идентификатор, можно генерировать на клиенте, удобно в распределённых системах. Но...
💣 Проблемы:
– Большой размер (16 байт vs 4 байта у INT)
– Плохая локальность: индекс B-Tree фрагментируется
– Медленнее вставки, особенно при высоких нагрузках
– Нагружает сеть, если часто передаёшь PK
📉 В PostgreSQL это особенно заметно: индекс на UUID-ключе может вести себя гораздо хуже, чем на
✅ Как делать правильно:
1. Если всё в одной БД: используй
2. Если нужен UUID:
– генерируй
– либо
– или комбинируй автоинкремент + случайный суффикс
3. Храни UUID как
🧠 UUID — мощный инструмент, но не серебряная пуля. Прежде чем делать его
Сохрани, чтобы не собирать фрагментированные индексы вручную 😅
#db
👉 @database_info
Выглядит красиво: глобально уникальный идентификатор, можно генерировать на клиенте, удобно в распределённых системах. Но...
💣 Проблемы:
– Большой размер (16 байт vs 4 байта у INT)
– Плохая локальность: индекс B-Tree фрагментируется
– Медленнее вставки, особенно при высоких нагрузках
– Нагружает сеть, если часто передаёшь PK
📉 В PostgreSQL это особенно заметно: индекс на UUID-ключе может вести себя гораздо хуже, чем на
BIGSERIAL.✅ Как делать правильно:
1. Если всё в одной БД: используй
BIGINT или BIGSERIAL2. Если нужен UUID:
– генерируй
UUID v7 (появился в 2022, содержит компонент времени → лучше упорядочен)– либо
UUID v1 (временной, но с оговорками по безопасности)– или комбинируй автоинкремент + случайный суффикс
3. Храни UUID как
UUID, а не как VARCHAR(36) — это экономит место и CPU🧠 UUID — мощный инструмент, но не серебряная пуля. Прежде чем делать его
PRIMARY KEY, подумай: что ты реально выигрываешь?Сохрани, чтобы не собирать фрагментированные индексы вручную 😅
#db
👉 @database_info
👍10👎3❤2
Почему одна и та же БД летает на staging и тормозит в проде
Знакомо? На staging сервере — отклик 100мс, на проде — секундные таймауты. Хотя база одна и та же, схема такая же. Что не так?
Вот 5 частых причин:
1. Разный объём данных
На staging — 10k строк, на проде — 10 млн. Индексы, которые "и так нормально", внезапно перестают справляться.
2. Отсутствие/различие индексов
DevOps мог не раскатить нужные индексы в прод. Или, наоборот, staging набит экспериментальными индексами.
3. Параметры конфигурации БД
4. Статистика устарела
На проде реже делается
5. Разное поведение приложения
Прод нагружается параллельно десятками потоков. Staging — ты и Postman.
🛠 Что делать:
– Сравни настройки сервера (
– Проверь
– Не доверяй staging — тестируй на продоподобных данных
#db
👉 @database_info
Знакомо? На staging сервере — отклик 100мс, на проде — секундные таймауты. Хотя база одна и та же, схема такая же. Что не так?
Вот 5 частых причин:
1. Разный объём данных
На staging — 10k строк, на проде — 10 млн. Индексы, которые "и так нормально", внезапно перестают справляться.
2. Отсутствие/различие индексов
DevOps мог не раскатить нужные индексы в прод. Или, наоборот, staging набит экспериментальными индексами.
3. Параметры конфигурации БД
work_mem, shared_buffers, max_connections — часто в staging минимальны, но в проде тоже забывают подкрутить.4. Статистика устарела
На проде реже делается
ANALYZE, планировщик начинает строить неэффективные планы. Итог — ползёт.5. Разное поведение приложения
Прод нагружается параллельно десятками потоков. Staging — ты и Postman.
🛠 Что делать:
– Сравни настройки сервера (
SHOW ALL;)– Проверь
EXPLAIN ANALYZE– Не доверяй staging — тестируй на продоподобных данных
#db
👉 @database_info
👍9🤣2❤1
Антипаттерн: использование
Кажется безобидным, правда? Особенно на этапе прототипирования. Но как только ваш запрос с
🔻 Почему это плохо:
– Избыточные данные. Вы тянете всё, включая ненужные поля. Это бьёт по сети, памяти и CPU.
– Ломкость кода. Добавили колонку в таблицу — и, внезапно, старый код падает, потому что ожидал другую структуру.
– Плохая читаемость. Непонятно, какие поля реально нужны. Это мешает отладке и сопровождению.
– Невозможно использовать covering index — индекс по нужным колонкам не спасёт, если вы вытаскиваете всё подряд.
📌 Как правильно:
✅ Явно указывайте нужные поля:
✅ Работаете с ORM — настраивайте выборку полей в
✅ В аналитике? Даже при джойнах и CTE — указывайте, что реально используете.
🧠 Запомни: чем меньше данных ты запрашиваешь — тем быстрее и стабильнее работает твой код.
💬 А ты встречал
#db
👉 @database_info
SELECT * в продакшенеКажется безобидным, правда? Особенно на этапе прототипирования. Но как только ваш запрос с
SELECT * уходит в прод, начинаются проблемы:🔻 Почему это плохо:
– Избыточные данные. Вы тянете всё, включая ненужные поля. Это бьёт по сети, памяти и CPU.
– Ломкость кода. Добавили колонку в таблицу — и, внезапно, старый код падает, потому что ожидал другую структуру.
– Плохая читаемость. Непонятно, какие поля реально нужны. Это мешает отладке и сопровождению.
– Невозможно использовать covering index — индекс по нужным колонкам не спасёт, если вы вытаскиваете всё подряд.
📌 Как правильно:
✅ Явно указывайте нужные поля:
SELECT id, name, created_at FROM users;
✅ Работаете с ORM — настраивайте выборку полей в
select() или .only() (в зависимости от фреймворка).✅ В аналитике? Даже при джойнах и CTE — указывайте, что реально используете.
🧠 Запомни: чем меньше данных ты запрашиваешь — тем быстрее и стабильнее работает твой код.
💬 А ты встречал
SELECT * в проде? Или, может, сам когда-то писал так?#db
👉 @database_info
👍12❤3
🔴 Антипаттерн: игнорирование поведения NULL в SQL
Когда ты пишешь
❌ Пример проблемы:
Если
✔️ Как избежать:
1. Явно учитывай NULL'ы:
2. Работай с COALESCE, если допустимо:
📌 То же касается и
📌 Агрегации (
Вывод:
NULL — не "ничего", а "неизвестно", и SQL строго это уважает. Не учитывая это, легко получить баг, который даже не заметишь сразу.
💡 Всегда проверяй поведение WHERE, JOIN и агрегатов с
Сохрани, чтобы не ловить баги на ровном месте.
#db
👉 @database_info
Когда ты пишешь
WHERE column != 'value', ты можешь думать, что фильтруешь всё, что не равно 'value'. Но если в колонке есть NULL, такие строки выпадут из выборки. Почему? Потому что NULL != 'value' даёт… UNKNOWN, а не TRUE.❌ Пример проблемы:
SELECT * FROM users
WHERE status != 'active';
Если
status у кого-то NULL — он не попадёт в результат. Неочевидно, но критично.✔️ Как избежать:
1. Явно учитывай NULL'ы:
SELECT * FROM users
WHERE status != 'active' OR status IS NULL;
2. Работай с COALESCE, если допустимо:
SELECT * FROM users
WHERE COALESCE(status, '') != 'active';
📌 То же касается и
=: NULL = 'value' → UNKNOWN📌 Агрегации (
COUNT, AVG`) тоже игнорируют `NULL — помни об этом при аналитикеВывод:
NULL — не "ничего", а "неизвестно", и SQL строго это уважает. Не учитывая это, легко получить баг, который даже не заметишь сразу.
💡 Всегда проверяй поведение WHERE, JOIN и агрегатов с
NULL. Пиши явный код, особенно в проде.Сохрани, чтобы не ловить баги на ровном месте.
#db
👉 @database_info
👍13❤2
📕 Практические кейсы использования ClickHouse для разработчиков, администраторов, специалистов по базам данных, Data engineers, Backend и FullStack-разработчиков
На открытом уроке 24 июля в 20:00 мск мы погрузимся в тонкости работы с ClickHouse:
📗 На вебинаре разберём:
1. Основные принципы работы, архитектура и преимущества использования ClickHouse;
2. Реальные кейсы использования ClickHouse для анализа веб-логов, IoT данных и финансовых транзакций;
📘 В результате на практике разберетесь в настройке и использовании ClickHouse для обработки больших объемов данных.
👉 Регистрация и подробности о курсе NoSQL: https://vk.cc/cNQL7R
Все участники открытого урока получат скидку на курс "NoSQL"
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
На открытом уроке 24 июля в 20:00 мск мы погрузимся в тонкости работы с ClickHouse:
📗 На вебинаре разберём:
1. Основные принципы работы, архитектура и преимущества использования ClickHouse;
2. Реальные кейсы использования ClickHouse для анализа веб-логов, IoT данных и финансовых транзакций;
📘 В результате на практике разберетесь в настройке и использовании ClickHouse для обработки больших объемов данных.
👉 Регистрация и подробности о курсе NoSQL: https://vk.cc/cNQL7R
Все участники открытого урока получат скидку на курс "NoSQL"
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Как понять, что вашему проекту нужен полнотекстовый поиск, а не
Часто разработчики в PostgreSQL начинают с простого:
Но уже при 10k+ строк и регулярных запросах начинаются тормоза. Значит, пора на следующий уровень — полнотекстовый поиск.
🔍 Когда
– Сложные запросы с несколькими
– Не масштабируется: без индексов → full scan
– Нет нормализации слов:
💡 Решение:
📈 Плюсы:
– Работают GIN-индексы
– Поддержка морфологии и синонимов
– Быстрее и точнее на больших объемах
⚠️ Подводные камни:
– Нужна настройка языкового словаря
–
– Требуется обновление индекса при INSERT/UPDATE
🛠 Как включить GIN-индекс:
👉 Если пользователи ищут по тексту — не тормозите
Сохрани, чтобы потом не мучиться с explain-ами 😉
#db
👉 @database_info
ILIKEЧасто разработчики в PostgreSQL начинают с простого:
SELECT * FROM articles WHERE noscript ILIKE '%postgres%';
Но уже при 10k+ строк и регулярных запросах начинаются тормоза. Значит, пора на следующий уровень — полнотекстовый поиск.
🔍 Когда
ILIKE — плохо:– Сложные запросы с несколькими
ILIKE– Не масштабируется: без индексов → full scan
– Нет нормализации слов:
postgres, PostgreSQL, постгрес — всё разное💡 Решение:
to_tsvector + to_tsquery
SELECT * FROM articles
WHERE to_tsvector('russian', noscript) @@ to_tsquery('russian', 'postgres');
📈 Плюсы:
– Работают GIN-индексы
– Поддержка морфологии и синонимов
– Быстрее и точнее на больших объемах
⚠️ Подводные камни:
– Нужна настройка языкового словаря
–
tsquery не такая гибкая, как regex– Требуется обновление индекса при INSERT/UPDATE
🛠 Как включить GIN-индекс:
CREATE INDEX idx_articles_noscript_search
ON articles USING GIN (to_tsvector('russian', noscript));
👉 Если пользователи ищут по тексту — не тормозите
ILIKE, внедряйте полнотекст!Сохрани, чтобы потом не мучиться с explain-ами 😉
#db
👉 @database_info
👍7❤3👎1
Отказоустойчивость от двух нод в облачных базах данных
Если вам важна бесперебойная работа вашего проекта, самое время позаботиться об отказоустойчивости. Selectel поможет сделать это проще и выгоднее — у провайдера можно создать отказоустойчивый кластер баз данных всего от двух нод.
Выгода очевидна: использование двух нод в кластере вместо стандартных трех позволяет сократить расходы на 33%.
Почему это надежно?
▪️SLA отказоустойчивого кластера — 99,95% на запись и 99,99% на чтение.
▪️Доступно автоматическое резервное копирование кластера «из коробки» и без доплат. Ежедневно создаются инкрементальные бэкапы, а полные копии кластера — раз в неделю.
▪️Можно создавать реплики в разных сегментах пула для большей надежности. При этом серверы кластера размещаются на разных физических хостах и имеют разные контуры питания.
Разверните отказоустойчивые кластеры облачных баз данных в Selectel: https://slc.tl/80ecr
Реклама, АО «Селектел», ИНН: 7810962785, ERID: 2VtzqxjxEBa
Если вам важна бесперебойная работа вашего проекта, самое время позаботиться об отказоустойчивости. Selectel поможет сделать это проще и выгоднее — у провайдера можно создать отказоустойчивый кластер баз данных всего от двух нод.
Выгода очевидна: использование двух нод в кластере вместо стандартных трех позволяет сократить расходы на 33%.
Почему это надежно?
▪️SLA отказоустойчивого кластера — 99,95% на запись и 99,99% на чтение.
▪️Доступно автоматическое резервное копирование кластера «из коробки» и без доплат. Ежедневно создаются инкрементальные бэкапы, а полные копии кластера — раз в неделю.
▪️Можно создавать реплики в разных сегментах пула для большей надежности. При этом серверы кластера размещаются на разных физических хостах и имеют разные контуры питания.
Разверните отказоустойчивые кластеры облачных баз данных в Selectel: https://slc.tl/80ecr
Реклама, АО «Селектел», ИНН: 7810962785, ERID: 2VtzqxjxEBa
🧱 Антипаттерн: использование UUID как Primary Key без оглядки
На первый взгляд, UUID — классный способ генерировать уникальные идентификаторы:
– не зависят от последовательности
– удобны для распределённых систем
– безопасны для внешнего экспонирования
Но если ты просто заменишь
❌ В чём подвох:
– Производительность INSERT'ов резко падает: UUID случайные → нет locality → индекс (обычно B-Tree) постоянно фрагментируется
– Индексы пухнут: UUID = 16 байт, BIGINT = 8 байт. Разница кажется небольшой, но на больших объёмах — это боль
– Чтение медленнее: за счёт увеличенного размера индексов и меньшего кэш-хита
✅ Как избежать:
1. Если нет жёсткой необходимости в UUID — не используй их как PK
2. Нужен UUID? Сделай его вторичным индексом, а PK оставь автоинкрементным
3. Или хотя бы используй UUID v7 (новый стандарт с time-based префиксом) — он улучшает локальность по сравнению с v4
Пример:
→ Внутри БД — быстрый
→ Для внешних API — UUID. Удобно и производительно.
#db
👉 @database_info
На первый взгляд, UUID — классный способ генерировать уникальные идентификаторы:
– не зависят от последовательности
– удобны для распределённых систем
– безопасны для внешнего экспонирования
Но если ты просто заменишь
SERIAL или BIGINT на UUID в качестве PK — жди сюрпризов:❌ В чём подвох:
– Производительность INSERT'ов резко падает: UUID случайные → нет locality → индекс (обычно B-Tree) постоянно фрагментируется
– Индексы пухнут: UUID = 16 байт, BIGINT = 8 байт. Разница кажется небольшой, но на больших объёмах — это боль
– Чтение медленнее: за счёт увеличенного размера индексов и меньшего кэш-хита
✅ Как избежать:
1. Если нет жёсткой необходимости в UUID — не используй их как PK
2. Нужен UUID? Сделай его вторичным индексом, а PK оставь автоинкрементным
3. Или хотя бы используй UUID v7 (новый стандарт с time-based префиксом) — он улучшает локальность по сравнению с v4
Пример:
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
public_id UUID DEFAULT gen_random_uuid() UNIQUE,
name TEXT
);
→ Внутри БД — быстрый
BIGINT,→ Для внешних API — UUID. Удобно и производительно.
#db
👉 @database_info
👍12👎2
This media is not supported in your browser
VIEW IN TELEGRAM
Хотите узнать секрет оптимизации SQL-запросов?
Очень важно понимать порядок выполнения.
В SQL-запросе операторы выполняются в следующем порядке:
1. FROM / JOIN
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. DISTINCT
7. ORDER BY
8. LIMIT / OFFSET
#db
👉 @database_info
Очень важно понимать порядок выполнения.
В SQL-запросе операторы выполняются в следующем порядке:
1. FROM / JOIN
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. DISTINCT
7. ORDER BY
8. LIMIT / OFFSET
#db
👉 @database_info
👍6
Бесплатный курс по PostgreSQL от практиков рынка
Присоединяйтесь к бесплатному курсу по основам PostgreSQL от Selectel и Эльбрус Буткемп. Он будет полезен Junior- и Middle-специалистам: администраторам баз данных, разработчикам, DevOps-инженерам и аналитикам.
Вы научитесь:
🔹создавать и связывать таблицы,
🔹выполнять базовые операции с данными,
🔹работать с РСУБД.
Бонусы: вы можете получить сертификат о прохождении курса, а также промокоды для практики на мощностях Selectel.
Начните обучение уже сегодня.
Реклама. АО «Селектел», ИНН 7810962785, ERID: 2VtzqxH9jwE
Присоединяйтесь к бесплатному курсу по основам PostgreSQL от Selectel и Эльбрус Буткемп. Он будет полезен Junior- и Middle-специалистам: администраторам баз данных, разработчикам, DevOps-инженерам и аналитикам.
Вы научитесь:
🔹создавать и связывать таблицы,
🔹выполнять базовые операции с данными,
🔹работать с РСУБД.
Бонусы: вы можете получить сертификат о прохождении курса, а также промокоды для практики на мощностях Selectel.
Начните обучение уже сегодня.
Реклама. АО «Селектел», ИНН 7810962785, ERID: 2VtzqxH9jwE
❤6
Индексы в PostgreSQL: Часть 1 — B-Tree
Если ты создавал индекс в PostgreSQL по умолчанию, значит, это B-Tree.
Но как он работает и когда он реально полезен?
Что это такое?
B-Tree индекс — сбалансированное дерево поиска.
PostgreSQL автоматически использует его для:
=\` (равенство)
> < >= <= (сравнения)
BETWEEN
LIKE 'abc%' (только префикс, без
Пример:
Запрос не будет сканировать всю таблицу — он сразу пойдёт по дереву.
Подводные камни:
1. Не работает для произвольных LIKE:
2. Осторожно с функциями:
3. Многоколонковые индексы:
Порядок важен.
Когда ставить?
- Уникальные поля (email, username).
- Часто используемые фильтры и JOIN-колонки.
- Сортировки (
Вывод:
B-Tree — твой “универсальный солдат”. Но не пихай его на всё подряд. Перед добавлением — смотри
Сохрани, чтобы не забыть!
#db
👉 @database_info
Если ты создавал индекс в PostgreSQL по умолчанию, значит, это B-Tree.
Но как он работает и когда он реально полезен?
Что это такое?
B-Tree индекс — сбалансированное дерево поиска.
PostgreSQL автоматически использует его для:
=\` (равенство)
> < >= <= (сравнения)
BETWEEN
LIKE 'abc%' (только префикс, без
%abc%).Пример:
CREATE INDEX idx_users_email ON users (email);
SELECT * FROM users WHERE email = 'test@example.com';
Запрос не будет сканировать всю таблицу — он сразу пойдёт по дереву.
Подводные камни:
1. Не работает для произвольных LIKE:
LIKE '%abc%' → индекс не поможет.2. Осторожно с функциями:
WHERE LOWER(email) = 'abc' — индекс не используется. Нужен функциональный индекс:
CREATE INDEX idx_users_email_lower ON users (LOWER(email));
3. Многоколонковые индексы:
Порядок важен.
(a, b) используется при фильтре по a или по a AND b, но не только по b.Когда ставить?
- Уникальные поля (email, username).
- Часто используемые фильтры и JOIN-колонки.
- Сортировки (
ORDER BY created_at DESC).Вывод:
B-Tree — твой “универсальный солдат”. Но не пихай его на всё подряд. Перед добавлением — смотри
EXPLAIN (ANALYZE).Сохрани, чтобы не забыть!
#db
👉 @database_info
👍18