С годами я убеждаюсь, что простых задач программирования не бывает. На первый взгляд они могут казаться простыми, но это лишь обман. Под поверхностью прячутся всевозможные чертики, только и ждущие, чтобы вырваться наружу.
В октябре 2000 года Даррен Тафт опубликовал в группе новостей по SQL Server задачу, которая выглядит лёгкой. Приведу его слова: «У меня есть система заказов, которая выделяет номера в пределах заранее определённых диапазонов. Сейчас я делаю это так: ...» На этом месте он привёл хранимую процедуру на диалекте T-SQL. В ней был цикл, который увеличивал значение request_id до тех пор, пока не находил пропуск в нумерации или пока попытка не проваливалась. Даррен продолжил: «Это годится для первых нескольких номеров, но когда диапазоны достигают 10 000 между минимумом и максимумом, всё начинает заметно тормозить. Может ли кто-нибудь придумать лучший способ?
Встроенный в базы данных Oracle “Client Result Cache” (CRC) является эффективным, интегрированным, управляемым кэшем, который резко улучшает производительность запросов и существенно снижает нагрузку на базу данных при повторяющихся запросах к по большей части статическим таблицам, таким как почтовые индексы или номера деталей. Никакие изменения в приложениях не требуются. Никакого отдельное промежуточного кэша устанавливать не нужно. CRC доступен для каждого "толстого" клиента, который использует библиотеки Oracle Client, такие как драйверы для Python, Node.js, Go, PHP, Rust, Ruby и Oracle C API. Он также доступен в JDBC. Эта статья демонстрирует пример для Python.
Преимущества кэширования результатов клиента
Может использоваться без необходимости изменять код приложения.
Улучшенное время отклика запроса.
Операторы не посылаются для выполнения в базу данных.
Лучшая производительность за счет устранения циклов обмена между серверами.
Улучшенная масштабируемость сервера баз данных за счет экономии ресурсов сервера.
Автоматически управляемое аннулирование кэша, поддерживающее соответствие кэша изменениям в базе данных.
Не требуется сервер промежуточного слоя для кэширования.
Разработчикам не требуется создавать или использовать собственный кэш.
SQL — первый язык программирования, в котором появились явные временные типы данных. Я давно полагаю, что если бы в Cobol изначально был тип TIMESTAMP, вся история с Y2K могла бы и не случиться. По крайней мере, сегодня всё больше людей знают о стандартах отображения даты и времени ISO 8601. Кто знает — может быть, их наконец начнут применять.
MariaDB и MySQL - две из наиболее широко используемых СУБД, доля которых на рынке среди реляционных баз данных совместно составляет более 40%. Хотя они имеют общую базовую реализацию, некоторые фундаментальные различия делают их более подходящими для различных сценариев.
В этой статье сравнения MariaDB и MySQL мы обратимся к истории этих технологий, исследуем их подобие и различие, чтобы помочь вам развеять сомнения относительно применения этих двух баз данных. Продолжить чтение "Детальное сравнение MariaDB и MySQL"
Индексы в MySQL являются одним из главных средств улучшения производительности запросов. Они особенно полезны, когда основные операции вашего проекта относятся к чтению данных, хранящихся в базе данных. Мы уже обсуждали нюансы индексов в MySQL, где говорилось, что MySQL предлагает вам для выбора различные типы SQL-индексов.
Основной тип индекса в MySQL - это индекс B-Tree, рассмотренный нами в одной из предыдущих статей. Если вы работаете с MySQL, то определенно знаете также о других нюансах индексов, одним из которых является тот факт, что индексы B-Tree могут строиться на нескольких столбцах (обычно их называют составными индексами). В этом примере мы используем MariaDB, хотя Percona Server для MySQL и MySQL Server будут вести себя идентично.
Ваш API замедляется. Вы проверяете базу данных и обнаруживаете 42 индекса в таблице users. Какие из них можно безопасно удалить? Во сколько они обходятся по производительности? Давайте разберёмся, что на самом деле происходит в Postgres, когда индексов слишком много.
Если вы бэкенд‑ или фуллстек‑инженер, вам, вероятно, не хочется становиться гуру индексации — вы просто хотите, чтобы API был быстрым и стабильным, без постоянного присмотра за pg_stat_user_indexes.
Обслуживание индексов включает несколько задач: удаление неиспользуемых индексов, удаление избыточных индексов и регулярную перестройку индексов для борьбы с фрагментацией (и, само собой, грамотную настройку autovacuum).
Есть много причин, почему набор индексов нужно держать «стройным», и некоторые из них не столь очевидны.
PostgreSQL 18 приносит целый ряд улучшений производительности, которые помогают приложениям работать эффективнее и дарят более приятный опыт пользователю. Одно из таких улучшений называется «skip scans» (пропуск просмотра). У многих на этом месте возникнет вопрос: звучит здорово, но что такое skip scan? Цель этой статьи — прояснить, как это работает, что именно делает и, что самое важное: как получить от этой возможности практическую пользу.
Одной из самых важных причин выбрать платформу как службу (PaaS), например, AWS RDS, является действительно легкая возможность выполнять восстановление к моменту времени. Давайте посмотрим на это.
Восстановление на момент времени
При подключении к консоли и просмотре ваших баз данных все, что вам требуется сделать - это выбрать вкладку “Maintenance and Backups” (обслуживание и резервные копии) для получения информации о том, какие бэкапы создаются:
Эта статья опирается на предыдущий материал «Введение в NUMA» (PostgreSQL и NUMA, часть 1 из 4) и предполагает не только знание определения NUMA, но и общее понимание аппаратной и программной реализации.
В этой части рассматривается взаимодействие PostgreSQL и Linux на системах с NUMA. Тема сложная, поэтому кое‑где используются упрощения. Тем не менее здесь собрана выжимка общих сведений о работе PostgreSQL 17 и ниже (а также PostgreSQL 18 без поддержки libnuma) на NUMA‑системах с Linux в качестве точки отсчёта. К концу чтения вы не только будете в состоянии уверенно запускать Postgres на NUMA‑системе, но и поймёте, почему поддержка libnuma в PostgreSQL 18 настолько важна.
Этот цикл посвящён особенностям работы PostgreSQL на крупных системах с большим числом процессоров. По моему опыту, столкнувшись с этой задачей, люди нередко тратят месяцы на освоение азов. Цель цикла — снять эти трудности, дав ясную базовую картину по ключевым темам. Хочется верить, что будущим инженерам и администраторам баз данных не придётся месяцами методом проб и ошибок разбираться в том, что можно понять быстрее.
Эти статьи сосредоточены на низкоуровневых «как» и «почему» в контексте неоднородного доступа к памяти (Non‑Uniform Memory Access), чтобы затем было проще понимать решения и рекомендации — с упором на концептуальную сторону. К сожалению, во многих местах без технических деталей не обойтись: голые концепции без деталей в лучшем случае сбивают с толку.
Дальнейшие части будут опираться на материал этой статьи. Рекомендуем начать с него, а затем по мере необходимости возвращаться.
Как я объяснял в докладе на PostgreSQL Conference Europe 2025, повреждение данных может незаметно случиться в любой базе PostgreSQL и останется так, пока мы физически не прочитаем повреждённые данные. Причин, по которым отдельные блоки в таблицах и других объектах могут быть испорчены, немало. Даже современное аппаратное обеспечение хранилищ далеко от безошибочности. Бинарные резервные копии, сделанные инструментом pg_basebackup (очень распространённая стратегия в мире PostgreSQL), скрывают эти проблемы, поскольку они не проверяют данные, а копируют файлы «как есть». С релизом PostgreSQL 18 сообщество решило по умолчанию включить контрольные суммы данных — серьёзный шаг к раннему обнаружению таких сбоев. В этой статье рассматривается, как PostgreSQL реализует контрольные суммы, как обрабатывает их несоответствия и как можно включить контрольные суммы в существующих кластерах.
Оператор MERGE позволяет написать один оператор DML с различными условиями для выполнения операций INSERT, UPDATE или DELETE в целевой таблице на основе источника данных. Он обеспечивает ряд преимуществ в плане производительности и не требует исключения или ограничения уникальности, в отличие от оператора INSERT ON CONFLICT.
Давайте рассмотрим пример с таблицей current_inventory, которую мы хотим обновить на основе транзакций, перечисленных в таблице daily_updates. Нам необходимо учесть все состояния (sale, new, remove, restock) в таблице daily_updates и выполнить необходимые операции с current_inventory.
Кроме того, мы реализуем функциональность обновления значения поля addinfo на “no sale” в current_inventory, если элемент отсутствует в daily_updates. Продолжить чтение "Оператор Merge в PostgreSQL 17"