Апгрейд для лінивих: як PostgreSQL 12 підвищує продуктивність

Апгрейд для лінивих: як PostgreSQL 12 підвищує продуктивність

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 мають одну проблему — вони роздуваються і займають зайве місце на диску, а продуктивність вилучення та оновлення даних знижується. Під «роздуванням» я маю на увазі неефективну підтримку індексної структури. Це може бути, а може й не бути, пов'язано зі сміттєвими кортежами, які видаляє ВАКУУМ (Дякую за інформацію Пітеру Гейгану (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 у таблицях з безліччю секцій.

Запис даних за допомогою КОПІЯ — до речі, це чудовий спосіб масового завантаження даних і ось приклад прийому 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 вже зараз стабільніше, ніж я припускав, не лінуйтеся якісно тестувати програми, перш ніж випускати їх у продакшен.

Джерело: habr.com

Додати коментар або відгук