Апгрейд для ленивых: как PostgreSQL 12 повышает производительность

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!


PostgreSQL 12, последняя версия «лучшей в мире реляционной базы данных с открытым исходным кодом», выходит через пару-тройку недель (если все пойдет по плану). Это соответствует обычному расписанию — новая версия с уймой новых возможностей выходит раз в год, и, честно говоря, это впечатляет. Поэтому я и стал активным членом сообщества PostgreSQL.


По-моему, в отличие от прошлых выпусков, PostgreSQL 12 не содержит одной-двух революционных функций (как, например, секционирование или параллелизм запросов). Я как-то пошутил, что главная фишка PostgreSQL 12 — в большей стабильности. А разве не это нужно, когда вы управляете критически важными данными вашего бизнеса?


Но PostgreSQL 12 этим не ограничивается: с новыми возможностями и усовершенствованиями приложения будут работать лучше, а от вас всего-навсего требуется сделать апгрейд!


(Ну, может, еще индексы перестроить, но в этом релизе это не так страшно, как мы привыкли.)


Вот будет здорово — апгрейднуть PostgreSQL и сразу наслаждаться значительными улучшениями без лишних телодвижений. Несколько лет назад я анализировал обновление с PostgreSQL 9.4 до PostgreSQL 10 и увидел, как ускорилось приложение благодаря улучшенному параллелизму запросов в PostgreSQL 10. И, главное, от меня почти ничего не требовалось (всего-то задать параметр конфигурации max_parallel_workers).


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


И как же простой апгрейд до PostgreSQL 12 сделает вас счастливым? Сейчас расскажу.


Серьезные улучшения индексирования


Без индексирования база данных далеко не уедет. А как еще быстро находить информацию? Фундаментальная система индексирования PostgreSQL называется B-дерево. Этот тип индекса оптимизирован для систем хранения.


Мы просто используем оператор CREATE INDEX ON some_table (some_column), а PostgreSQL проделывает большую работу, чтобы поддерживать актуальность индекса, пока мы постоянно вставляем, обновляем и удаляем значения. Все работает само по себе, как по волшебству.


Но у индексов PostgreSQL есть одна проблема — они раздуваются и занимают лишнее место на диске, а производительность извлечения и обновления данных снижается. Под «раздуванием» я подразумеваю неэффективное поддержание индексной структуры. Это может быть — а может и не быть — связано с мусорными кортежами, которые удаляет VACUUM (спасибо за информацию Питеру Гейгану (Peter Geoghegan)). Раздувание индекса особенно заметно в рабочих нагрузках, где индекс активно изменяется.


PostgreSQL 12 серьезно улучшает работу индексов B-дерева, и эксперименты с тестами типа TPC-C показали, что места теперь используется, в среднем, на 40% меньше. Теперь мы тратим меньше времени не только на обслуживание индексов B-дерева (то есть на операции записи), но и на извлечение данных, ведь индексы стали гораздо меньше.


Приложения, которые активно обновляют свои таблицы — обычно это OLTP-приложения (обработка транзакций в режиме реального времени) — будут гораздо эффективнее использовать диск и обрабатывать запросы. Чем больше на диске места, тем больше у базы данных пространства для роста без апгрейда инфраструктуры.


Некоторые стратегии апгрейда требуют перестроить индексы B-дерева, чтобы воспользоваться этими преимуществами (например, pg_upgrade не перестроит индексы автоматически). В предыдущих версиях PostgreSQL перестройка больших индексов в таблицах приводила к значительному простою, ведь в это время нельзя было вносить изменения. Но в PostgreSQL 12 есть еще одна классная фишка: теперь можно перестраивать индексы параллельно командой REINDEX CONCURRENTLY, чтобы совсем избежать простоя.


В PostgreSQL 12 есть и другие улучшения инфраструктуры индексирования. Еще одна штука, где не обошлось без волшебства, — журнал упреждающей записи, он же WAL (write-ahead log). Журнал упреждающей записи записывает каждую транзакцию в PostgreSQL на случай сбоя и репликации. Приложения используют его для архивации и восстановления на момент времени. Конечно, журнал упреждающей записи записывается на диск, а это может отразиться на производительности.


В PostgreSQL 12 сократились издержки записей WAL, которые создаются индексами GiST, GIN и SP-GiST при построении индекса. Это дает несколько ощутимых преимуществ: записи WAL занимают меньше места на диске, а данные быстрее воспроизводятся, например во время восстановления после сбоя или восстановления на момент времени. Если вы используете такие индексы в своих приложениях (например, геопространственные приложения на основе PostGIS много используют индекс GiST), это еще одна фича, которая значительно улучшит работу безо всяких усилий с вашей стороны.


Секционирование — больше, лучше, быстрее


В PostgreSQL 10 появилось декларативное секционирование. В PostgreSQL 11 его стало гораздо проще использовать. В PostgreSQL 12 можно менять масштаб секций.


В PostgreSQL 12 производительность системы секционирования стала значительно лучше, особенно если в таблице тысячи секций. Например, если запрос затрагивает всего несколько секций в таблице, где их тысячи, он будет выполняться гораздо быстрее. Производительность улучшена не только для таких типов запросов. Еще вы заметите, как ускорились операции INSERT в таблицах со множеством секций.


Запись данных с помощью COPY — кстати, это отличный способ массовой загрузки данных и вот пример приема JSON — в секционированные таблицы в PostgreSQL 12 тоже стала эффективнее. С COPY и так все было быстро, а в PostgreSQL 12 совсем летает.


Благодаря этим преимуществам в PostgreSQL можно хранить наборы данных еще большего размера, а извлекать их стало проще. И никаких усилий с вашей стороны. Если у приложения много секций, например, оно записывает данные временных рядов, простой апгрейд значительно улучшит его производительность.


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


Запросы WITH стали гораздо лучше


Когда был применен патч для встроенных обобщенных табличных выражений (они же CTE, они же запросы WITH), мне не терпелось написать статью о том, как обрадовались разработчики приложений с PostgreSQL. Это одна из тех фич, которые ускорят приложение. Если, конечно, вы используете CTE.


Я часто замечаю, что новички в SQL любят использовать CTE: если написать их определенным образом, прямо чувствуешь, что пишешь императивную программу. Лично я любил переписывать эти запросы, чтобы обойтись без CTE и увеличить производительность. Сейчас все иначе.


PostgreSQL 12 позволяет встраивать определенный тип CTE без побочных эффектов (SELECT), который используется только один раз ближе к концу запроса. Если бы я вел статистику запросов с CTE, которые я переписывал, большинство из них попали бы в эту категорию. Это помогает разработчикам писать понятный код, который теперь еще и быстро работает.


Более того, PostgreSQL 12 оптимизирует выполнение SQL сам, вам не придется ничего делать. И хотя теперь, наверное, мне не нужно будет оптимизировать такие запросы, здорово, что PostgreSQL продолжает работать над оптимизацией запросов.


Just-in-Time (JIT) — теперь по умолчанию


В системах PostgreSQL 12 с поддержкой LLVM JIT-компиляция включена по умолчанию. Во-первых, вы получаете поддержку JIT для некоторых внутренних операций, а во-вторых, запросы с выражениями (самый простой пример — x + y) в списках выбора (которые стоят у вас после SELECT), агрегатами, выражениями с предложениями WHERE и другими могут использовать JIT для повышения производительности.


Раз JIT включен в PostgreSQL 12 по умолчанию, производительность улучшится сама по себе, но я советую потестить приложение в PostgreSQL 11, где только появился JIT, чтобы измерить производительность запросов и узнать, нужно ли что-нибудь настраивать.


А как же остальные новые фичи PostgreSQL 12?


В PostgreSQL 12 уйма новых классных фич — от возможности изучать данные JSON с помощью стандартных выражений маршрута SQL/JSON до многофакторной аутентификации с параметром clientcert=verify-full, создаваемых столбцов и многого другого. Хватит на отдельный пост.


Как и PostgreSQL 10, PostgreSQL 12 повысит общую производительность сразу после апгрейда. У вас, конечно, может быть свой путь — протестируйте приложение при схожих условиях в рабочей системе, прежде чем включать улучшения, как это сделал я с PostgreSQL 10. Даже если PostgreSQL 12 уже сейчас стабильнее, чем я предполагал, не ленитесь качественно тестировать приложения, прежде чем выпускать их в продакшен.

Источник: https://habr.com/ru/company/southbridge/blog/466727/


Интересные статьи

Интересные статьи

Сделал dashboard Postgresql overview для postgres_exporter. Чем отличается от других дашбородов postgres_exporter? Я объединил все другие дашборды postgres_exporter в один. Этот дашборд показы...
Предлагаю ознакомиться с расшифровкой доклада 2018 года Андрея Сальникова "Практика обновления версий PostgreSQL" В большинстве своем, системные администраторы и ДБА бояться как огня д...
Если ваши микросервисы уже используют общую базу PostgreSQL для хранения данных, или ей пользуются несколько экземпляров одного сервиса на разных серверах, можно относительно «дешево» получить во...
Но если для интернет-магазина, разработанного 3–4 года назад «современные» ошибки вполне простительны потому что перед разработчиками «в те далекие времена» не стояло таких задач, то в магазинах, сдел...
Статья публикуется от имени Ахальцева Иоанна, Jiga Tinkoff.ru сегодня — это не просто банк, это IT-компания. Она предоставляет не только банковские услуги, но ещё выстраивает экосистему вокруг...