{Perm} DEV Meetup #1

MySQL и PostgreSQL

что «под капотом» и почему это важно знать прикладному разработчику

Никита Стрелков, разработчик e-commerce подразделения, VK

Обо мне

Никита Стрелков
Разработчик в проекте PayDay

  • Go/PHP разработчик
  • 8+ лет в программировании, весь продакшен опыт на backend
  • ведущий преподаватель курса СУБД в Технопарке МГТУ им. Баумана
  • nikita.strelkov@gmail.com
  • Telegram: @NikitaStrelkov

О чем доклад

  • Сравнение функциональности
  • Процессная/потоковая модель сервера
  • Путь выполнения запроса
  • MVCC
  • Индексы

Почему, а главное зачем?

Сравнение функциональности

Функция PostgreSQL 14+ MySQL 8+
CTE Есть Есть
Декларативное секционирование Есть Есть
Полнотекстовый поиск Есть Есть
GIS и SRS Есть Есть
JSON Есть Есть
Логическая репликация Есть Есть
Полусинхронная репликация Есть Есть
Оконные функции Есть Есть
Tранзакционный DDL Есть Есть

Процессы и потоки

Процессы PostgreSQL

postgres process model

Процессы PostgreSQL

$ pstree -p 43545
-+= 00001 root /sbin/launchd
 \-+= 43545 n.strelkov /usr/local/bin/postgres -D /usr/local/var/postgres
   |--= 43547 n.strelkov postgres: checkpointer
   |--= 43548 n.strelkov postgres: background writer
   |--= 43549 n.strelkov postgres: walwriter
   |--= 43550 n.strelkov postgres: autovacuum launcher
   |--= 43551 n.strelkov postgres: stats collector
   |--= 43552 n.strelkov postgres: logical replication launcher
   |--= 48886 n.strelkov postgres: n.strelkov postgres [local] idle
   \--= 49086 n.strelkov postgres: n.strelkov movielens [local] idle in transaction
            

Процессы MySQL

$ pstree -p 50249
-+= 00001 root /sbin/launchd
 \-+= 50136 n.strelkov /bin/sh /usr/local/opt/mysql/bin/mysqld_safe \
                --datadir=/usr/local/var/mysql
   \--- 50249 n.strelkov /usr/local/opt/mysql/bin/mysqld \
                --basedir=/usr/local/opt/mysql \
                --datadir=/usr/local/var/mysql \
                --plugin-dir=/usr/local/opt/mysql/lib/plugin \
                --log-error=n-strelkov.err \
                --pid-file=n-strelkov.pid
            

Потоки MySQL

mysql> show processlist\G
*************************** 1. row ***************************
     Id: 5
   User: event_scheduler
   Host: localhost
     db: NULL
Command: Daemon
   Time: 539
  State: Waiting on empty queue
   Info: NULL
*************************** 2. row ***************************
     Id: 8
   User: root
   Host: localhost
     db: NULL
Command: Query
   Time: 0
  State: init
   Info: show processlist
*************************** 3. row ***************************
     Id: 9
   User: root
   Host: localhost
     db: NULL
Command: Sleep
   Time: 437
  State:
   Info: NULL
3 rows in set (0.00 sec)

MySQL

Connection ID

mysql> select connection_id()\G
*************************** 1. row ***************************
connection_id(): 8
1 row in set (0.01 sec)

MySQL

количество активных потоков

mysql> show global status like 'threads_running'\G
*************************** 1. row ***************************
Variable_name: Threads_running
        Value: 2
1 row in set (0.00 sec)

Connection pool

PostgreSQL MySQL
PGPool-II
и/или
PgBouncer
Client-side
connection pool

Путь запроса PostgreSQL

pg query path

Путь запроса MySQL

mysql query path

Статистика

Статистика по таблицам

MySQL PostgreSQL
Размер кластерного индекса Размер таблицы
количество строк количество строк
количество страниц в памяти

Статистика по атрибутам

MySQL PostgreSQL
Распределение данных, в т.ч. доля null значений Доля null значение
Средний размер колонки в байтах
Количество уникальных значений
Статистическая корреляция между физическим порядком строк и логическим порядком значений столбца
Распределение данных
Наиболее часто встречаемые значения и их частота

Межатрибутная статистика

MySQL PostgreSQL
Функциональные зависимости
Количество уникальных значений
Atomicity - Атомарность
Consistency - Согласованность
Isolation - Изолированность
Durability - Долговечность

MVCC

Multi Version Concurrency Control

MVCC PostgreSQL

pg mvcc

MVCC 1: TABLE

action
TXID: 103
xmin
xmax id name notes
100 0 1 Alice Great at programming
101 0 2 Bob Always talk to alice
102 0 3 Eve Listens to everyone's conversations

MVCC 2: UPDATE

action
TXID: 103
xmin
xmax id name notes
100 0 1 Alice Great at programming
- update 101 0 2 Bob Always talk to alice
102 0 3 Eve Listens to everyone's conversations

MVCC 3: UPDATE IN PROGRESS

action
TXID: 103
xmin
xmax id name notes
100 0 1 Alice Great at programming
- update 101 103 2 Bob Always talk to alice
102 0 3 Eve Listens to everyone's conversations

MVCC 4: UPDATE IN PROGRESS

action
TXID: 103
xmin
xmax id name notes
100 0 1 Alice Great at programming
- update 101 103 2 Bob Always talk to alice
102 0 3 Eve Listens to everyone's conversations
+ update 103 0 2 Bob Working very hard

MVCC 5: UPDATED

action
TXID: 104
xmin
xmax id name notes
100 0 1 Alice Great at programming
101 103 2 Bob Always talk to alice
102 0 3 Eve Listens to everyone's conversations
103 0 2 Bob Working very hard

MVCC 6: INSERT

action
TXID: 104
xmin
xmax id name notes
100 0 1 Alice Great at programming
101 103 2 Bob Always talk to alice
102 0 3 Eve Listens to everyone's conversations
103 0 2 Bob Working very hard
+ insert 104 0 4 Dave Very promising new-hire

MVCC 7: INSERTED

action
TXID: 105
xmin
xmax id name notes
100 0 1 Alice Great at programming
101 103 2 Bob Always talk to alice
102 0 3 Eve Listens to everyone's conversations
103 0 2 Bob Working very hard
104 0 4 Dave Very promising new-hire

MVCC 8: DELETE

action
TXID: 105
xmin
xmax id name notes
100 0 1 Alice Great at programming
101 103 2 Bob Always talk to alice
- delete 102 105 3 Eve Listens to everyone's conversations
103 0 2 Bob Working very hard
104 0 4 Dave Very promising new-hire

MVCC 9: DELETED

action
TXID: 106
xmin
xmax id name notes
100 0 1 Alice Great at programming
101 103 2 Bob Always talk to alice
102 105 3 Eve Listens to everyone's conversations
103 0 2 Bob Working very hard
104 0 4 Dave Very promising new-hire

MVCC MySQL InnoDB

mysql innodb mvcc

Сравнение реализаций MVCC

  1. Размер старой версии объекта
  2. INSERT
  3. Восстановление предыдущей версии в случае отката транзакции
  4. Освобождение места занятого старой версией
  5. Влияние задержек очистки мертвых кортежей
  6. Последовательное сканирование "распухшей таблицы"
  7. Индексы

Индексы

Индекс

Два основных типа архитектуры индекса:

  • Кластерный индекс
  • Некластерный индекс

Кластерный индекс

Проиндексированное значение хранится вместе с данными.

Данные хранятся в отсортированном виде в порядке заданном индексом.

У таблицы может быть только один индекс такого типа.

Некластерный индекс

Проиндексированные значения и данные хранятся отдельно.

Индекс содержит указатели на остальные данные строки.

Так же известен, как "вторичный индекс" (secondary index).

Индексы в PostgreSQL

Все индексы являются некластерными(вторичными), так как данные хранятся отдельно в табличной куче (Table Heap)

Есть механизм кластеризации данных по индексу

Индексы в PostgreSQL

Есть поддержка составных, частичных и функциональных индексов.

CREATE INDEX idx_users_age_gender
                ON people(age, gender); -- составной

CREATE INDEX idx_users_age_partial
                ON people(age) where age >= 25; -- частичный

CREATE INDEX idx_users_names
                ON people(LOWER(name)); -- функциональный
            

Индексы в PostgreSQL

Большой выбор встроенных типов индексов:

  • B-Tree Index
  • Hash Index
  • GIN (Generalized Inverted Index)
  • GiST (Generalized Search Tree)
  • SP-GiST (Space Partitioned GiST)
  • (BRIN) Block Range Index

Индексы в MySQL

В таблице может быть 1 кластерный и несколько некластерных вторичных индексов.

Индексы в MySQL

  • Поддерживает в явном виде только B+ Tree тип индекса.
  • Hash индексы используются самим движком InnoDB в служебных целях.
  • Поддерживает Index Hints
SELECT * FROM table1 USE INDEX (col1_index,col2_index)
  WHERE col1=1 AND col2=2 AND col3=3;

SELECT * FROM table1 IGNORE INDEX (col3_index)
  WHERE col1=1 AND col2=2 AND col3=3;
            

Спасибо за внимание!

Материалы: