Базы данных PostgreSQL с высокой нагрузкой на запись могут исчерпать идентификаторы транзакций (transaction IDs). Обычно это становится проблемой при достижении около 2 миллиардов транзакций. В критический момент PostgreSQL завершает работу, чтобы предотвратить повреждение данных.
Для большинства приложений это никогда не вызывает проблем. Но для систем с очень интенсивной записью за этим нужно следить.🤵
Обычно решение заключается в выполнении VACUUM или настройке параметров автovacuum, чтобы строки и транзакции корректно очищались.
Если вы хотите проверить, насколько вы близки к wraparound (переполнению XID), вот запрос для диагностики:
👉 @SQLPortal
Для большинства приложений это никогда не вызывает проблем. Но для систем с очень интенсивной записью за этим нужно следить.
Обычно решение заключается в выполнении VACUUM или настройке параметров автovacuum, чтобы строки и транзакции корректно очищались.
Если вы хотите проверить, насколько вы близки к wraparound (переполнению XID), вот запрос для диагностики:
WITH max_age AS (
SELECT
2000000000 AS max_old_xid,
setting AS autovacuum_freeze_max_age
FROM pg_catalog.pg_settings
WHERE name = 'autovacuum_freeze_max_age'
),
per_database_stats AS (
SELECT
datname,
m.max_old_xid::int,
m.autovacuum_freeze_max_age::int,
age(d.datfrozenxid) AS oldest_current_xid
FROM pg_catalog.pg_database d
JOIN max_age m ON (true)
WHERE d.datallowconn
)
SELECT
MAX(oldest_current_xid) AS oldest_current_xid,
MAX(ROUND(100 * (oldest_current_xid / max_old_xid::float))) AS percent_towards_wraparound,
MAX(ROUND(100 * (oldest_current_xid / autovacuum_freeze_max_age::float))) AS percent_towards_emergency_autovac
FROM per_database_stats;
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤5👍3
Давайте попрактикуемся в SQL
Из приведённых выше таблиц напишите SQL-запрос, который находит продавцов (salespeople) и клиентов (customers), проживающих в одном городе
👉 @SQLPortal
Из приведённых выше таблиц напишите SQL-запрос, который находит продавцов (salespeople) и клиентов (customers), проживающих в одном городе
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥1
Знаете ли вы, что в Postgres есть функция для подсчёта промежуточных и общих итогов? Вместо написания отдельных
Они позволяют автоматически вычислять промежуточные и общие итоги по измерениям в вашем запросе. В сочетании с
👉 @SQLPortal
SUM
или ручной работы в таблицах, используйте операторы ROLLUP
и CUBE
Они позволяют автоматически вычислять промежуточные и общие итоги по измерениям в вашем запросе. В сочетании с
date_trunc
можно агрегировать данные по неделям, месяцам или годамPlease open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2
Секреты оптимизации SQL-запросов
Вот 20 проверенных техник, которые я регулярно использую для оптимизации SQL-запросов:😊
👉 @SQLPortal
Вот 20 проверенных техник, которые я регулярно использую для оптимизации SQL-запросов:
• Грамотно используйте индексы:
Индексируйте критически важные столбцы, используемые в WHERE, JOIN, ORDER BY и GROUP BY.
• Избегайте SELECT *:
Выбирайте только необходимые столбцы, чтобы сократить объём передаваемых данных и время обработки.
• Реализуйте пагинацию корректно:
Используйте OFFSET и FETCH NEXT или пагинацию методом поиска (seek method) для эффективного постраничного вывода.
• Ограничивайте количество строк как можно раньше:
Применяйте фильтрацию на ранних этапах, чтобы максимально сократить размер выборки.
• Избегайте функций в WHERE:
Функции над столбцами блокируют использование индексов — переписывайте условия, используя «сырые» столбцы.
• Упрощайте JOIN:
Минимизируйте количество соединений и избегайте избыточных JOIN-ов.
• Выбирайте правильные типы JOIN:
Используйте INNER JOIN, LEFT JOIN или EXISTS там, где это уместно, чтобы избежать лишней обработки данных.
• Используйте корректные типы данных:
Сопоставляйте типы данных в JOIN и WHERE, чтобы обеспечить эффективное использование индексов.
• Запрашивайте только изменённые данные:
Реализуйте инкрементальную обработку, а не полный повторный запрос таблиц.
• Группируйте операции:
Пакетная вставка, обновление или удаление снижают накладные расходы на транзакции.
• Исключайте избыточные подзапросы:
Используйте JOIN или CTE вместо повторяющихся подзапросов.
• Используйте EXISTS вместо IN:
EXISTS часто работает быстрее, чем IN, особенно на больших объёмах данных.
• Нормализуйте с умом:
Балансируйте между нормализацией и денормализацией в производительно критичных запросах.
• Применяйте материализованные представления:
Предварительно рассчитывайте сложные агрегации и запросы для ускорения чтения.
• Анализируйте планы выполнения:
Регулярно проверяйте execution plan, чтобы находить и устранять ресурсоёмкие операции.
• Избегайте подстановок с начальным %:
LIKE '%abc' не использует индексы эффективно.
• Делайте транзакции короткими:
Сокращайте время выполнения транзакций, чтобы уменьшить блокировки и конфликты.
• Регулярно обновляйте статистику:
Актуальные статистики обеспечивают точное планирование запросов СУБД.
• Используйте подсказки (query hints) с осторожностью:
Применяйте только после тестирования и при необходимости конкретной оптимизации.
• Постоянно отслеживайте и настраивайте:
Регулярно анализируйте производительность запросов и проактивно оптимизируйте медленные запросы.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥2
Что происходит, когда данные в Postgres превышают размер страницы в 8 КБ? Они TOASTятся. 🍞
TOAST-таблицы — это механизм, с помощью которого Postgres хранит большие значения, разбивая их на несколько частей и распределяя по нескольким страницам. TOAST полезен тем, что позволяет хранить JSON и другие крупные типы данных. Однако это может немного повлиять на производительность.
Если у вас много больших значений, стоит пересмотреть модель данных — возможно, получится сделать её менее TOAST-зависимой.
▶️ Подробнее — в полном блоге о
👉 @SQLPortal
TOAST-таблицы — это механизм, с помощью которого Postgres хранит большие значения, разбивая их на несколько частей и распределяя по нескольким страницам. TOAST полезен тем, что позволяет хранить JSON и другие крупные типы данных. Однако это может немного повлиять на производительность.
Если у вас много больших значений, стоит пересмотреть модель данных — возможно, получится сделать её менее TOAST-зависимой.
TOAST
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
50 практических вопросов по SQL для отработки навыков запросов, часто появляющихся на собеседованиях
> SQL‑скрипты для создания тестовых данных (таблицы, вставка строк)
> Вопросы типа: «Напишите запрос, чтобы вывести уникальные значения», «Найдите N‑ю максимальную зарплату» и т.д.
> Готовые решения и объяснения
▶️ читать
👉 @SQLPortal
> SQL‑скрипты для создания тестовых данных (таблицы, вставка строк)
> Вопросы типа: «Напишите запрос, чтобы вывести уникальные значения», «Найдите N‑ю максимальную зарплату» и т.д.
> Готовые решения и объяснения
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥1
Совет по логированию в Postgres для повышения производительности: включите логирование временных файлов (log_temp_files).
Зачем?
Идеально — установить
Если лимит превышен — происходит сброс на диск (spill), и создаётся временный файл не меньше, чем
Пример настройки: логировать временные файлы больше 4 МБ (в килобайтах), соответствует текущему значению work_mem:
Пример лога временного файла:
То есть операция сортировки превысила work_mem, и была выгружена во временный файл.🥰
👉 @SQLPortal
Зачем?
Идеально — установить
log_temp_files
в значение, равное текущему work_mem
.work_mem
— это лимит оперативной памяти на одну операцию. Если операция укладывается в этот лимит, временные файлы не создаются и логирование не требуется.Если лимит превышен — происходит сброс на диск (spill), и создаётся временный файл не меньше, чем
work_mem
.Пример настройки: логировать временные файлы больше 4 МБ (в килобайтах), соответствует текущему значению work_mem:
log_temp_files = '4096'
Пример лога временного файла:
2024-05-16 14:23:05.123 UTC [12345] user@database LOG: temporary file: path "base/pgsql_tmp/pgsql_tmp1234.0", size 245760
2024-05-16 14:23:05.123 UTC [12345] user@database DETAIL: Sort operation used temporary file because work_mem was exceeded
То есть операция сортировки превысила work_mem, и была выгружена во временный файл.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍1
Постройте надёжную основу для звёздных схем (star schemas) в Oracle Database, следуя этим рекомендациям от Дани Шнайдера:
Измерения (Dimension)
> Первичный ключ на суррогатном ключе
> Уникальное ограничение на колонке(ах) бизнес-ключа
Факты (Facts)
> Внешний ключ и битмаповый индекс на каждой колонке измерения
📖 Читать: ссылка
👉 @SQLPortal | #cтатья
Измерения (Dimension)
> Первичный ключ на суррогатном ключе
> Уникальное ограничение на колонке(ах) бизнес-ключа
Факты (Facts)
> Внешний ключ и битмаповый индекс на каждой колонке измерения
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Когда следует сбрасывать статистику в Postgres?
Модуль
Чтобы сбросить статистику вручную, выполните:
1) Сразу после значительных изменений в запросах
Если вы внесли серьёзные изменения в код приложения, оптимизировали SQL-запросы или изменили индексы, сброс
2) При проведении тестов производительности
Если вы запускаете бенчмарки или тесты производительности запросов, сброс
3) После крупных операций по обслуживанию
После операций вроде
@SQLPortal
Модуль
pg_stat_statements
в Postgres собирает статистику в течение длительного времени. Эти данные могут устаревать, и если вы полагаетесь на них для оптимизации запросов, сброс статистики поможет быстрее получить актуальную информацию.Чтобы сбросить статистику вручную, выполните:
SELECT pg_stat_statements_reset();
1) Сразу после значительных изменений в запросах
Если вы внесли серьёзные изменения в код приложения, оптимизировали SQL-запросы или изменили индексы, сброс
pg_stat_statements
поможет точнее измерить эффект этих изменений.2) При проведении тестов производительности
Если вы запускаете бенчмарки или тесты производительности запросов, сброс
pg_stat_statements
гарантирует, что результаты будут отражать только те запросы, которые выполнялись в рамках теста.3) После крупных операций по обслуживанию
После операций вроде
pg_repack
, переиндексации или изменения структуры таблиц стоит сбросить pg_stat_statements
, чтобы оценить, как эти изменения повлияли на производительность.@SQLPortal
❤2👍2
Как исполняется SQL-запрос в базе данных?
Разберём на примере:
1. Transport Subsystem
Запрос прилетает по сети и попадает в транспортный уровень базы.
2. Query Processor
SQL парсится → строится Query Parse Tree — дерево, где разбираются:
> SELECT → какие колонки
> FROM → из какой таблицы
> WHERE → какое условие
3. Execution Engine
На основе дерева создаётся Execution Plan:
> индексный поиск по city_index
> выборка колонок name, age
> возврат подходящих строк
4. Storage Engine
Работает с физическими данными через:
> Transaction Manager
> Lock Manager
> Buffer Manager
> Recovery Manager
Это вся цепочка — от строки запроса до результата в твоей IDE.📝
👉 @SQLPortal
Разберём на примере:
SELECT name, age FROM users WHERE city = 'San Francisco'
1. Transport Subsystem
Запрос прилетает по сети и попадает в транспортный уровень базы.
2. Query Processor
SQL парсится → строится Query Parse Tree — дерево, где разбираются:
> SELECT → какие колонки
> FROM → из какой таблицы
> WHERE → какое условие
3. Execution Engine
На основе дерева создаётся Execution Plan:
> индексный поиск по city_index
> выборка колонок name, age
> возврат подходящих строк
4. Storage Engine
Работает с физическими данными через:
> Transaction Manager
> Lock Manager
> Buffer Manager
> Recovery Manager
Это вся цепочка — от строки запроса до результата в твоей IDE.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤6
Общие рекомендации по распределению памяти в Postgres:
🔸 25% — на
🔸 25% — на
🔸 50% — резерв для файлового кэша ОС, системных процессов и служебных операций (например, VACUUM), использующих
👉 @SQLPortal
shared_buffers
(кэш буферов). Чаще всего запрашиваемые данные должны помещаться в кэш. Проверьте коэффициент попаданий в кэш (cache hit ratio) — 98–99% запросов должны обслуживаться из кэша (хотя это зависит от нагрузки).work_mem
, распределённый между соединениями. Значение work_mem
, умноженное на max_connections, должно составлять примерно 25% от общего объёма памяти.maintenance_work_mem
Please open Telegram to view this post
VIEW IN TELEGRAM
👀4🔥3❤2
Используйте иерархический профилировщик (hierarchical profiler) для поиска узких мест в коде PL/SQL. Это позволит вам детально анализировать производительность и находить функции или блоки, которые вызывают наибольшие задержки.
Пример использования:
Начиная с версии Oracle 18c иерархический профилировщик был улучшен и теперь позволяет хранить данные трассировки в таблицах, упрощая последующий анализ и оптимизацию.☺️
👉 @SQLPortal
Пример использования:
DECLARE
-- создание таблиц для хранения данных профилирования
DBMS_HPROF.CREATE_TABLES();
-- запуск профилирования и получение идентификатора сессии профилирования
id NUMBER := DBMS_HPROF.START_PROFILING;
-- ваш PL/SQL код, который нужно профилировать
<code>
-- завершение профилирования
DBMS_HPROF.STOP_PROFILING;
-- анализ данных профилирования с выводом отчета в формате HTML
DBMS_HPROF.ANALYZE(id, report_clob => html);
END;
Начиная с версии Oracle 18c иерархический профилировщик был улучшен и теперь позволяет хранить данные трассировки в таблицах, упрощая последующий анализ и оптимизацию.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
Таймауты запросов находятся в самом верху нашего списка рекомендаций для любой базы данных — будь то маленький pet-проект или крупная продакшен-БД. Мы часто говорим об этом, но если вы вдруг пропустили — выставляйте таймаут запроса от одной до двух минут:
Это предотвратит выполнение запросов, которые «убегают» и начинают потреблять ресурсы сверх меры.
Вы можете установить
👉 @SQLPortal
ALTER DATABASE dbname SET statement_timeout = '60s';
Это предотвратит выполнение запросов, которые «убегают» и начинают потреблять ресурсы сверх меры.
Вы можете установить
statement_timeout
на уровне базы данных, пользователя или сессии. Мы рекомендуем установить глобальный таймаут в Postgres, а затем переопределять его для отдельных пользователей или сессий, которым требуется больше времени на выполнение.Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2
Ограничения (constraints) в базе данных это хорошая практика: они задают правила на уровне данных, обеспечивая корректность, согласованность и надёжность информации в приложении.
Ограничения предотвращают запись некорректных или противоречивых данных в таблицы.
–
–
Ограничения также поддерживают связи между полями.
–
Многие ORM и приложения тоже реализуют валидации, но дублирование проверки на уровне кода и на уровне базы — это хорошая практика.
Есть туториал по работе с constraints, с примерами кода:
👉 https://crunchydata.com/developers/playground/postgres-constraints-tutorial
👉 @SQLPortal
Ограничения предотвращают запись некорректных или противоречивых данных в таблицы.
–
NOT NULL
гарантирует, что обязательные поля не останутся пустыми.–
CHECK
проверяет, что значения соответствуют заданным условиям (например, age > 0).Ограничения также поддерживают связи между полями.
–
FOREIGN KEY
обеспечивает ссылочную целостность между таблицами. Например, нельзя создать заказ для несуществующего клиента.Многие ORM и приложения тоже реализуют валидации, но дублирование проверки на уровне кода и на уровне базы — это хорошая практика.
Есть туториал по работе с constraints, с примерами кода:
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥1
MongoDB MCP Server полностью изменил мой способ взаимодействия с базами данных.
Вместо того чтобы переключаться между 5 AI-инструментами, теперь я просто общаюсь с базой данных напрямую в IDE.
Показать пользователей, зарегистрированных на этой неделе → мгновенный SQL-запрос.
Как это использовать с Claude, VS Code и Windsurf:
1. Claude Desktop для анализа данных
Можно исследовать сложные данные без единого SQL-запроса.
Просто задаешь вопрос на естественном языке — и сразу получаешь инсайты.
Переход между таблицами, выявление паттернов и связь сущностей — всё в рамках одной простой беседы.
2. VS Code + GitHub Copilot
Создание пользователей, назначение прав, управление кластерами — буквально за секунды.
Администрирование Atlas — прямо из VS Code, без переключения вкладок.
Ты сосредоточен на разработке, AI берёт на себя всю операционку.
3. Windsurf AI + встроенный MongoDB MCP Server
Они вышли на новый уровень:
— выбираешь шаблон сервера, подключение происходит в один клик.
— загружаешь схему — и получаешь сгенерированные data-access-слои с полной типобезопасностью.
Настройка MCP-сервера максимально простая:
10 секунд. Никаких конфигураций. AI-агент подключён.
▶️ GitHub репозиторий: https://fnf.dev/4e74Eag
👉 @SQLPortal
Вместо того чтобы переключаться между 5 AI-инструментами, теперь я просто общаюсь с базой данных напрямую в IDE.
Показать пользователей, зарегистрированных на этой неделе → мгновенный SQL-запрос.
Как это использовать с Claude, VS Code и Windsurf:
1. Claude Desktop для анализа данных
Можно исследовать сложные данные без единого SQL-запроса.
Просто задаешь вопрос на естественном языке — и сразу получаешь инсайты.
Переход между таблицами, выявление паттернов и связь сущностей — всё в рамках одной простой беседы.
2. VS Code + GitHub Copilot
Создание пользователей, назначение прав, управление кластерами — буквально за секунды.
Администрирование Atlas — прямо из VS Code, без переключения вкладок.
Ты сосредоточен на разработке, AI берёт на себя всю операционку.
3. Windsurf AI + встроенный MongoDB MCP Server
Они вышли на новый уровень:
— выбираешь шаблон сервера, подключение происходит в один клик.
— загружаешь схему — и получаешь сгенерированные data-access-слои с полной типобезопасностью.
Настройка MCP-сервера максимально простая:
docker run --rm -i mongodb/mongodb-mcp-server:latest
10 секунд. Никаких конфигураций. AI-агент подключён.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍3
Supabase работает над Multigres — решением для шардинга PostgreSQL, которое позволит масштабировать базу данных до петабайтного уровня
👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯5👍2