• MariaDB 10.3 – 25 мая 2018 • MariaDB 10.2 – 23 мая 2017 • MySQL 8.0 – 19 апреля 2018 • MySQL 5.7 – 21 октября 2015 • Percona Server for MySQL 8.0 – 21 декабря 2018 • Percona Server for MySQL 5.7 – 23 февраля 2016
Х не был выбран?” – Оптимизатор его рассматривал вообще? – Какая была его стоимость (Неправильная статистика?) • Какие преобразования делались – Сгенерированные запросы часто имеют “бессмысленные” части • WHERE col=123 ORDER BY col – Делаются ли преобразования вида “WHERE colX=10 AND func(colX)” -подзапр> “func(10)” ? • Разница между двумя версиями или машинами – diff /tmp/trace_from_host1.json /tmp/trace_from_host2.json • Какое-подзапрто автоматическое использование?
большим количеством вложенных VIEW с algorithm=merge • Резкое замедление после небольших изменений в одном из VIEW – EXPLAIN показывает, что algorithm=merge больше не используется • Сначала подозревали LEFT JOIN’ы ы "view": { "table": "view_name_8", "select_id": 9, "algorithm": "merged" } "view": { "table": "view_name_8", "select_id": 9, "algorithm": "materialized", "cause": "Not enough table bits to merge subquery" } • (из-подзапрза Table Elimination, EXPLAIN показывал <64 таблицы и до, и после)
преобразования – какие рассматриваются [фрагменты] планов запросов • Анализировать надо самому • Также полезно прикладывать к bug reports • Сейчас печатает самое главное – Дальше больше
• Оптимизатор MySQL/MariaDB использует индекс, как большую гистограмму (records_in_range) – Без этого – данных о selectivity нет. • Информация о распределении данных • Главным образом, condition selectivity select ... from ... where orders.ship_date BETWEEN '2019-06-01' AND '2019-06-10' and ... user.country = 'Russia' and...
persistent for ... set optimizer_use_stat_tables=4; set use_stat_tables='preferably'; <сложный запрос>; • Гистограммы появились в MariaDB 10.0 • Сбор статистики дорогой – Читает всю таблицу (и все индексы) – Строит гистограмму из всех данных (это дорого) • Сборку и использование надо включать вручную • => Распространены меньше, чем хотелось бы
on ... <сложный запрос>; • Похожи на MariaDB: • Хранятся как JSON, можно сделать больше buckets, ... • Построение тоже недешево: – На основе @@histogram_generation_max_mem_size определяем, сколько % данных участвует в гистограмме – Читаем всю таблицу – Bernoulli sampling (кидаем монетку для каждой записи)
– use_stat_tables=’preferably_for_queries’ – optimizer_use_condition_selectivity=... • Сборка по-подзапрпрежнему читает всю таблицу – И Bernoulli sampling (кидаем монетку для каждой записи) • Построение гистограммы: @@analyze_sample_percentage – default=100 -подзапр из всех данных – 0 -подзапр “автоматический размер выборки” – n% -подзапр использовать n% данных.
не важна :-подзапр( • Требует консерватизма в сборке гистограмм • Проблема сложная – PostgreSQL: очень ограниченное решение в последней версии) select ... from cars where manufacturer='Ford' and model='Focus 3' and year between 2012 and 2014 and engine_hp between 120 and 150 and embedded_gps = 'Yes' and ...
раньше • Помогают оптимизатору выбрать хороший план • Собирать надо вручную, теперь это делают одной командой: analyze table t persistent for columns(...) indexes (...) analyze table t persistent for all; – полный просмотр таблицы – set @@analyze_sample_percentage=0 • Аккуратно с корреляцией колонок и большим числом условий – гистограммы только по одной
table) (или CTE) (select customer_id, SUM(amount) as TOTAL_AMT from orders where order_date BETWEEN '2017-10-01' and '2017-10-31' group by customer_id) create view oct_totals as
клиентов (select customer_id, SUM(amount) as TOTAL_AMT from orders where order_date BETWEEN '2017 group by customer_id) create view oct_totals as select * from oct_totals where customer_id IN (1,2) ... having customer_id IN (1,2) select ... from customer C, oct_totals where C.name_uniq_key='Ivan' and C.customer_id = oct_totals.customer_id
tables, views, нерекурсивные CTEs. • MariaDB 10.3: Condition pushdown через PARTITION BY в window functions • MariaDB 10.4 – Condition pushdown из HAVING во WHERE – Condition pushdown в IN (SELECT ...) подзапросы во WHERE • MySQL: не поддерживает • PostgreSQL: поддерживает*, кроме нерекурсивных CTEs (исправят в PG12)
выполнить мгновенно alter table t1 add column col1 int; ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE. alter table t1 ... ,algorithm=instant; • MariaDB 10.3, MySQL 8.0: instant ADD COLUMN • Более ранние версии – INPLACE преобразования
добавить колонку не в конец • ALTER TABLE ... DROP COLUMN • Увеличение длины VARCHAR(n), INT -подзапр> BIGINT • Многие “расширяющие” изменения character set – utf8 -подзапр> utf8mb4 • Для не-подзаприндексных колонок – смена collation • Для колонок в индексах – смена collation на тот, у которого сортировка “покрывает” текущую
t( x INT, start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START, end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END, PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp) ) WITH SYSTEM VERSIONING; CREATE TABLE t( x INT, ) WITH SYSTEM VERSIONING; • Таблица может поддерживать версионирование: • Колонки для версий можно объявить явно:
SELECT * FROM t FOR SYSTEM_TIME AS OF TIMESTAMP'2016-10-09 08:07:06'; SELECT * FROM t; • Можно смотреть в прошлое • Или изучать период в прошлом: SELECT * FROM t FOR SYSTEM_TIME FROM '2016-01-01 00:00:00' TO '2017-01-01 00:00:00'; SET @@system_versioning_asof= TIMESTAMP'2016-10-09 08:07:06'
нельзя • Подоходит для – Аудита – Логирования всех действий – Возможности восстановления данных • Еще там есть partitioning, привязка к номеру транзакции, ... • Доступно в MariaDB 10.3
БД, а не той области, про которую данные – период применимости данных= время внесения изменений в БД – Редактировать историю нельзя • Application-подзапрtime: – Приложение в явном виде управляет start_time/end_time – Возможность вносить данные до/после события – Редактирование истории, будущего и тд.
DELETE FROM emp FOR PORTION OF emp_period FROM DATE '2019-06-01' TO DATE '2019-07-01' WHERE emp_name='John'; • Вносят изменение во временной диапазон SELECT * FROM emp; +----------+------------+------------+ | emp_name | start_date | end_date | +----------+------------+------------+ | John | 2015-01-01 | 2019-06-01 | | John | 2019-07-01 | 2020-12-31 | +----------+------------+------------+
каждого пользователя • root@localhost может использовать unix socket plugin – Пользователю root пароль не будет нужен – Остальных не пустят – => Нету беспарольного root@localhost после установки (и debian-подзапрsys-подзапрmaint тоже) • Изменения в системных таблицах – mysql.user -подзапр> mysql.global_priv • Истечение паролей
– улучшенные гистограммы – улучшенный Condition pushdown • InnoDB – больше покрытие мгновенных ALTER TABLE • Galera 4 • Application time for system-подзапрversioned tables • и много чего еще!