14500
Присоединяйтесь к нашему каналу и погрузитесь в мир баз данных Связь: @devmangx РКН: https://clck.ru/3H4Wo3
Это лучшая статья про MVCC в MySQL, что я читал.
MySQL и Postgres используют разные инженерные подходы для решения одной и той же задачи: undo log против нескольких версий кортежей.
Ещё одна отличная работа от Jeremy Cole.
👉 @SQLPortal
pgcli и mycli — отличные апгрейды по сравнению со стандартными клиентами psql и mysql.
Есть автодополнение, подсветка синтаксиса и в целом куда приятнее пользоваться.
Если заходишь к базе прямо из терминала, ставь их как можно раньше.
👉 @SQLPortal
Вставки в БД всегда про компромисс по производительности: либо пишем быстро и раскладываем всё по полкам позже, либо сразу платим за организацию данных.
Хорошо видно на примере MySQL и Postgres. В MySQL с InnoDB новые строки сразу падают в кластерный индекс. Это даёт быстрые последующие выборки, но вставка сама по себе дороже из-за обхода дерева, вставки в нужное место и возможного page split.
Postgres просто пишет новые строки в файл страниц/кортежей, из-за чего вставка получается попроще, но оптимизация места (VACUUM) откладывается на потом. Плюс индексы обновляются отдельно, потому что они хранятся вне основного файла таблицы.
На картину влияет и формат хранения: B-деревья против LSM-деревьев.
В B-деревьях вставка требует больше работы сразу. LSM разнесён по уровням, и система регулярно делает фоновые проходы и слияния. Запись выглядит «быстрее» (вкинули данные в in-memory слой), но потом движок постоянно занимается оптимизацией.
Отдельная история — журнал (binlog, WAL и так далее). Логи позволяют ускорить запись, перенося обновление реальных структур на диск до чекпоинта или вытеснения страницы.
Даже с этим механизмом заметно, насколько падает или растёт производительность в зависимости от того, сколько работы откладывается «на потом».
👉 @SQLPortal
MongoDB выкатывает внезапный праздничный фичерелиз
К РАСШИРЕННОМУ РЕЛИЗУ
Пало-Альто, Калифорния — MongoDB с радостью объявляет о MongoBleed™, инновационной фиче, которая проактивно делится содержимым вашей базы данных со всем интернетом.
«Годы нам говорили: как сделать наши чувствительные данные доступнее?» — говорит вымышленный спикер. — «MongoBleed отвечает на этот запрос. Никакой авторизации. Никакого согласия. Просто свободный, беспрепятственный поток данных наружу».
Ключевые возможности:
- Zero-Click Sharing: пароли сами уходят в интернет
- Десятилетие доверия: тихая бета с 2015 года
- Релиз под праздники: ничто так не говорит «С Рождеством», как продакшен-секреты на GitHub
- Elastic Integration: писали явно люди, которые «поняли задачу» по-своему
Отзывы пользователей:
«Я ел рождественский ужин, когда прилетел пейдж. База начала делиться логинами по всему миру. Семья реально сплотилась — вокруг моего ноутбука, пока я плакал». — вполне настоящий IT-админ
Что дальше?
Планы на 2026:
- Автоматическая рассылка паролей на Shodan
- AI-добыча секретов (они тоже в AI теперь, а как же)
- Интеграция со Slack, которая шлёт ваш .env прямо в #general
О MongoDB: MongoDB — база, которая верит, что данные хотят быть свободными. Очень свободными.
👉 @SQLPortal
Startup vs Total Cost
PostgreSQL считает для каждой операции два показателя:
Startup Cost — работа до первой строки результата. Для seq scan почти ноль, потому что строки можно отдавать сразу. Для sort - сначала надо отсортировать весь набор, и только потом появятся строки на вывод.
Total Cost — startup плюс выполнение до конца, то есть стоимость получения всех строк.
Пример на базе pagila:
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM film WHERE rental_duration = 5;
Seq Scan on film (cost=0.00..76.50 rows=191 width=390) (actual time=0.013..0.252 rows=191 loops=1)
Filter: (rental_duration = 5)
Rows Removed by Filter: 809
Buffers: shared hit=64
Planning Time: 0.063 ms
Execution Time: 0.274 ms
cost=0.00..76.50 означает:Buffers: shared hit=64 говорит, что запрос прошёл по 64 страницам буферного кеша. На этих страницах и строится стоимость:Чтение страниц: 1.0 × 64 страниц = 64.0
Обработка строк: 0.01 × 1000 строк = 10.0
Проверка фильтра: 0.0025 × 1000 строк = 2.5
Итого: ~76.5
Свежак: Elasticsearch не обязателен. BM25 уже есть в Postgres.
Теперь поиск можно закрывать прямо в базе. Postgres для всего.
Читать
👉 @SQLPortal
sqlit — это TUI в стиле lazygit для работы с SQL в терминале.
Поддерживает больше 10 баз (Postgres, SQLite, Supabase, ClickHouse, DuckDB и другие), есть история запросов, автодополнение и прочие удобства.
https://terminaltrove.com/sqlit/
👉 @SQLPortal
SQL встречается с семантическим поиском 🔥
Обычные базы данных не понимают естественный язык. Векторные базы не умеют точно фильтровать.
Knowledge Base Algebra от MindsDB решает эту проблему. И всё это полностью open-source.
Можно подключить больше 200 источников данных — как структурированных, так и неструктурированных и собрать единую базу знаний, которая объединяет семантический поиск, фильтрацию по метаданным и сложную булеву логику (SQL) в одной системе.
Пользователи просто пишут запросы обычным языком. Всё.
Для примера взяли рекомендательную систему фильмов с базой на 300k+ тайтлов. У части данных чёткие поля (жанр, рейтинг, год), а у большинства сплошной бардак (сюжеты, отзывы, куски текста).
С привычными инструментами вариантов немного:
Писать жёсткие SQL-фильтры и терять смысл
Использовать LLM, которая просто угадывает
С MindsDB можно задавать вопрос на естественном языке. Система сама определяет, где нужен семантический поиск, где фильтры, где логика, и возвращает точный результат.
И главное всё это можно запускать локально, прямо на своей машине.
👉 @SQLPortal
Делаешь ли ты эти типичные ошибки в SQL?
Забываешь про NULL
Обрабатываешь данные в памяти Java
Используешь JDBC-пагинацию для больших выборок
Применяешь агрегатные функции вместо оконных
Лукас Эдер объясняет, как делать правильно — и приводит ещё 7 распространённых ошибок.
👉 @SQLPortal
Интересный факт про vector search: проверка меньшего объёма данных делает поиск быстрее и точнее.
Алгоритм HNSW это основа одних из самых быстрых векторных поисков. Если вы использовали Weaviate или другие векторные базы, вы уже сталкивались с HNSW, это стандартный тип индекса, и не случайно.
HNSW можно представить как многоуровневую транспортную систему для векторов: сверху —> редкие длинные связи для глобальной навигации, средний уровень —> средние связи для регионального поиска, низкий уровень —> плотные связи для всех векторов для точного результата. Поиск начинается сверху, постепенно уточняется на каждом слое и в конце достигает максимальной точности на нижнем уровне. Алгоритм «перепрыгивает» через множество неактуальных данных вместо проверки каждого вектора, что делает его быстрее brute-force методов.
Основные параметры, которые можно настраивать:
• maxConnections —> плотность графа; большее значение повышает точность, но замедляет поиск и требует больше памяти
• ef, efConstruction —> динамический размер списков для поиска и построения графа, влияющий на баланс между скоростью и точностью
HNSW это баланс между скоростью, точностью и расходом памяти; улучшение одного всегда требует компромисса с другими.
Подробнее о настройке HNSW и оптимизации: Weaviate docs
👉 @SQLPortal
Использую Beekeeper Studio больше полугода и это самый удобный и красивый бесплатный менеджер баз данных, с которым мне доводилось работать. Приятен интерфейс, удобные горячие клавиши, интуитивная навигация, а подсветка и подтверждение перед удалением файлов делают работу безопасной.
Бесплатная версия покрывает большинство нужных функций, подписка не нужна. Рекомендую всем попробовать. 😎
GitHub: beekeeper-studio
👉 @SQLPortal
На официальной вики PostgreSQL опубликована статья “Don’t Do This”, где собраны типичные ошибки при работе с базой данных и объясняется, почему их стоит избегать
👉 @SQLPortal
Скрытые возможности PostgreSQL
В материале автор делится пятью возможностями, о которых редко говорят в сообществе PostgreSQL. Среди них — GRANT SELECT, DISTINCT ON, ограничения EXCLUDE и другие интересные приемы.
Читать статью: тык
👉 @SQLPortal
Где разместить базу данных бесплатно
Актуальные бесплатные платформы на сегодня ↓
🟢MongoDB Atlas
MongoDB — 512 МБ, автоматические бэкапы
→ mongodb.com
🟢Neon Tech
PostgreSQL — 500 МБ, 190 часов вычислений
→ neon.tech
🟢FreeDB Tech
MySQL — 25 МБ, максимум 200 подключений
→ freedb.tech
🟢Turso
SQLite — 5 ГБ, до 500 миллионов чтений
→ turso.tech
🟢Upstash
Redis — 256 МБ, 500 000 команд
→ upstash.com
🟢Xata
PostgreSQL — 15 ГБ, безлимитный трафик
→ lite.xata.io
🟢Supabase
PostgreSQL — 500 МБ, 5 ГБ трафика
→ supabase.com
🟢CockroachDB
10 ГБ хранилища, 50 млн запросов
→ cockroachlabs.com
🟢Koyeb
PostgreSQL — 1 ГБ, 5 часов выполнения
→ koyeb.com
👉 @SQLPortal
Совет по Postgres для тестирования расширений:
Можно использовать команду LOAD, чтобы подгрузить общие библиотеки только в рамках текущей сессии, вместо изменения shared_preload_libraries и перезапуска Postgres.
LOAD 'auto_explain';
LOAD 'pg_stat_statements';
Кое-что полезное: учебное пособие по SQL для анализа данных
ЗАБИРАЕМ ЗДЕСЬ
👉 @SQLPortal
Как планировщик оценивает план выполнения запросов
Раз уж разобрались с cost’ами и статистикой, посмотрим, как PostgreSQL реально собирает и выбирает план.
Планировщик разбивает запрос на части и считает стоимость каждой отдельно.
Для каждой таблицы в запросе PostgreSQL оценивает разные варианты доступа. Пройтись по всей таблице seq scan? Использовать индекс? Задействовать несколько индексов вместе? Каждый вариант получает свою оценку стоимости на основании параметров cost’ов и статистики, о которых говорили в пред постах.
Для join’ов между таблицами PostgreSQL перебирает разные алгоритмы: nested loop, hash join, merge join. Каждый вариант также получает оценку.
Итоговая стоимость плана — это сумма всех операций: сканирование таблиц, join’ы, сортировки, фильтры. PostgreSQL генерирует несколько полноценных планов, считает итоговую стоимость каждого.
Побеждает тот, у которого минимальная оценка. Именно его PostgreSQL и исполнит.
Подход снизу вверх: оцениваем отдельные операции, собираем их в полный план, выбираем самый дешёвый. Так PostgreSQL ориентируется в огромном пространстве вариантов. Дальше посмотрим, как он оценивает варианты доступа к таблицам.
👉 @SQLPortal
Просмотр статистики
PostgreSQL держит всю эту инфу в системных каталогах, которые можно дернуть обычным запросом.
-- Базовая статистика по таблице
SELECT schemaname, relname, n_live_tup, n_dead_tup
FROM pg_stat_user_tables
WHERE relname = 'film';
-- Результат:
-- schemaname | relname | n_live_tup | n_dead_tup
-- -----------+---------+------------+------------
-- public | film | 1000 | 0
-- Статистика по колонкам
SELECT tablename, attname, n_distinct, null_frac,
most_common_vals, most_common_freqs,
correlation
FROM pg_stats
WHERE tablename = 'film' AND attname = 'rental_duration';
-- Результат:
-- tablename | attname | n_distinct | null_frac | most_common_vals | most_common_freqs | correlation
-- ----------+-----------------+------------+-----------+-------------------+----------------------------------------+-------------
-- film | rental_duration | 5 | 0 | {6,3,4,5,7} | {0.212,0.203,0.203,0.191,0.191} | 0.163
Статистика: понимание своих данных
Формулы стоимости ничего не стоят без точного представления о данных. Сколько строк пройдёт по WHERE? Сколько уникальных значений у колонки? Какие значения встречаются чаще всего? Ответы на эти вопросы дают именно статистики.
Команда ANALYZE в PostgreSQL берёт выборку из таблиц и строит статистические сводки. Эти данные участвуют во всех решениях планировщика. Именно они отделяют нормальный план выполнения от полного провала.
Что отслеживает PostgreSQL
Для каждой колонки PostgreSQL хранит набор статистик:
Row Counts: количество живых строк в каждой таблице. Это база для всех оценок - если планировщик не знает примерный размер таблицы, он не сможет адекватно прикинуть стоимость запроса.
Null Fraction: доля NULL-значений. Когда вы пишете WHERE column IS NOT NULL, именно эта метрика помогает планировщику понять, насколько фильтр будет выборочным.
Most Common Values (MCVs): самые частые значения и их частоты. PostgreSQL хранит до ~100 таких значений на колонку.
Почему MCV важны. Представим таблицу:
-- У большинства фильмов rental_duration = 6 (21.2%), остальные распределены ровнее
SELECT * FROM film WHERE rental_duration = 6;
-- MCV показывает 21.2% → вероятнее всего последовательное сканирование
SELECT * FROM film WHERE rental_duration = 7;
-- MCV показывает 19.1% → всё ещё относительно выборочно
SELECT * FROM payment WHERE amount BETWEEN 5.00 AND 10.00;
Шаги SQL-запроса
Когда выполняется SQL-запрос:
SELECT owner, count(*)
FROM cats
WHERE owner != 3
GROUP BY owner
HAVING count(*) = 2
ORDER BY owner DESC;
PostgreSQL позволяет клонировать базу на 6 ГБ за 212 миллисекунд вместо 67 секунд. Вот как это работает.
Клонирование баз данных полезно в нескольких сценариях:
* тестирование миграций без трогания продакшн-данных
* поднятие свежих копий под каждый прогон тестов
* сброс sandbox-окружения между сессиями
* воспроизводимые снапшоты для отладки
Когда база весит несколько мегабайт, pg_dump вполне справляется. Но когда речь идёт о сотнях гигабайт, «просто сделать копию» превращается в серьёзный узкий момент.
В PostgreSQL система шаблонов была всегда. Каждый CREATE DATABASE тихо клонирует template1 под капотом, и вместо template1 можно использовать любую базу.
В версии 15 появился параметр STRATEGY, и по умолчанию включили WAL_LOG — поблочное копирование через журнал предзаписи (WAL). I/O становится ровнее, но для больших баз это медленнее.
В PostgreSQL 18 появилась опция file_copy_method = clone. На современных файловых системах вроде XFS, ZFS или APFS она использует операцию FICLONE. Вместо копирования байтов файловая система создаёт новые метаданные, которые указывают на те же физические блоки. Обе базы используют одно и то же хранилище, пока вы ничего не меняете.
Всю магию здесь делает файловая система, создавая copy-on-write (CoW) клон файлов.
Когда вы обновляете строку, файловая система запускает copy-on-write только для затронутых страниц. Всё остальное остаётся общим. Клон на 6 ГБ изначально не занимает дополнительного места и растёт только по мере расхождения данных.
Важно помнить один момент: у исходной базы не должно быть активных подключений во время клонирования. Это ограничение PostgreSQL, а не файловой системы.
Довольно круто.
👉 @SQLPortal
Новости: выпущена версия pgFormatter v5.9
pgFormatter пусть и не идеален, но это самый продвинутый форматтер и бьютификатор SQL и PL/pgSQL, заточенный именно под PostgreSQL. Поставляется как CLI-утилита или CGI-программа.
В этом релизе добавили ряд улучшений форматирования и закрыли проблемы, о которых пользователи сообщали с прошлого выпуска.
Основные изменения:
- Исправлено несколько проблем с форматированием JOIN
- Починены отступы после RAISE EXCEPTION ... USING
- Исправлено кривое форматирование CASE с присваиванием переменных
- Добавлен CI-экшен для прогона pgFormatter при каждом commit push
- Исправлена обработка dollar-quoted строк, когда разделитель прилеплен к слову
- Починены отступы у UNION в RETURN QUERY
- Исправлен false negative при детекте ключевых слов QUERY после RETURN
- Добавлен конфиг pre-commit hook
- Исправлено форматирование PL/pgSQL с DECLARE и CASE
- Починено форматирование научной нотации с экспонентами
- Исправлено ошибочное удаление лишних скобок в CREATE POLICY
- Закрыты проблемы с форматированием в PL/pgSQL при использовании DECLARE и CASE
Полный список изменений смотри в release notes
👉 @SQLPortal
onedump позволяет создавать резервные копии и восстанавливать базы данных MySQL и PostgreSQL на локальном компьютере, S3, Google Drive, Dropbox или SFTP с помощью одного инструмента.
https://github.com/liweiyi88/onedump
👉 @SQLPortal
Совет для PostgreSQL: используйте NULLS LAST или NULLS FIRST в ORDER BY, чтобы управлять расположением NULL‑значений в результатах запроса.
Пример:
SELECT order_id, product_name
FROM orders
ORDER BY order_date DESC NULLS FIRST;
В Oracle SQL вы можете вычесть один год из даты с помощью одного из вариантов:
ADD_MONTHS(dt, -12)
- INTERVAL '1' YEAR
ADD_MONTHS → 29 февраля преобразуется в 28 февраля предыдущего годаINTERVAL → 29 февраля преобразуется в 29 февраля предыдущего года → ошибка!
Инструмент командной строки для мониторинга активности сервера PostgreSQL
https://github.com/dalibo/pg_activity
👉 @SQLPortal
На GitHub опубликован бесплатный «6-недельный дорожный план по SQL для Data Science / аналитики»
Проект предлагает по неделе на ключевые темы: основы SQL и SELECT, агрегаты и GROUP BY, JOIN-ы, оконные функции, CTE и подзапросы, а затем — самостоятельные проекты для закрепления навыков 😎
👉 @SQLPortal
Как добиться index-only scan в Postgres?
Используйте covering indexes (покрывающие индексы).
SELECT name, email FROM web_users WHERE id = 123;
CREATE INDEX idx_users_includes
ON web_users (id)
INCLUDE (name, email);
auto_explain.log_min_duration = '1000ms';
Индексируйте скалярные значения в массивах JSON, хранящихся в Oracle Database, с помощью
CREATE MULTIVALUE INDEX ... ON t ( t.json_data.array.<type> )
JSON_EXISTS ( t.json_data, '$.array?(@.<type> == ... )' )
Чтобы кешировать результаты вызовов функций в PL/SQL, объявляйте их с модификаторами:
DETERMINISTIC ⇒ кеширование в пределах одного SQL-выражения
RESULT_CACHE ⇒ кеширование между сессиями
Перед использованием убедитесь, что функции имеют ограниченное количество уникальных входных данных и действительно являются детерминированными.
https://mikesmithers.wordpress.com/2022/10/16/deterministic-and-result_cache-pl-sql-functions/
👉 @SQLPortal