Нужно ли переходить на MySQL 5.6?

После выхода новой версии MySQL в начал этого года, многие задумались о том стоит ли на неё переходить с более старых версий. Чтобы ответить на этот вопрос для себя, вначале необходимо понять, а что именно даст этот переход. В этой статье я постараюсь осветить новые, важные для меня, фичи, которые были включены в дистрибутив новой версии, анализ их производительности и работоспособность новой версии, а так же необходимость что-то менять в коде в связи в переписанным оптимизатором. Так как объем изменений действительно очень велик, для каждого пункта дам ссылку на оригинальную статью по тестирования производительности и исключу из описания воду.

Начнем с самого интересного — расширения оптимизатора

Index Condition Pushdown (ICP) — данная оптимизация производится, если мы получаем доступ к данным в таблице с использованием составного индекса. Если условие на первую часть ключа может быть применено явно, а условие на оставшуюся часть ключа явно применено быть не может к примеру:

  • keypart1 = 1 — предикат доступа, keypart2 like ‘%value%’ — предикат фильтрации,
  • или же наложить на на обе части ключа range условие keypart1 between a and b — предикат доступа, keypart2 between c and d — предикат фильтрации (полное использование индекса для данного типа запросов в качестве предиката доступа в MySQL до сих пор не реализовано),

то ранее сервер MySQL, после применения предиката доступа, сделал бы переключение на storage engine и, прочитав строку таблицы, применил бы второе условие. С использованием данной опции, этого переключения не будет, конечно если сам storage engine поддерживает ICP, на данный момент это MyISAM и InnoDB, и применение предиката фильтрации будет произведено исключительно на основании данных индекса. В плане будет стоять Using index condition.
Согласно тестированию производительность при запросе данных из кэша составит порядка 30-50 процентов, при работе же с подсистемой ввода вывода возможно ускорение до 100 раз.
Multi Range Read (MRR) — при проведение Range Scan с использованием вторичных ключей, для уменьшения количества произвольных дисковых чтений, вначале считываем все необходимые данные из индекса, затем производим сортировку поROWID, и только после этого читаем данные по первичному ключу. В плане, что несомненно замечательно, будет стоятьUsing MRR. Данная операция является балковой. Т.е. применяя предикаты доступа по вторичному ключу — заполняем доступный буфер, и только после этого производим сортировку и чтение данных. Тут уж либо повезло и данные близко друг к другу либо нет. Для распределенных таблиц ситуация ещё лучше но это выходит за рамки этой статьи. В чистом виде данный алгоритм может быть применен при выполнении запроса по одной таблице. В сочетании с Batch Key Access (BKA) он так же заметно позволяет ускорить и операции джойнов. По умолчанию флаг BKA выключен, его значение, как и любое значение флагов оптимизатора можно посмотреть выполнив запрос SELECT @@optimizer_switch. При включение BKA необходимо провести проверки ваших запросов на разных значениях параметра join_buffer_size так как именно этот параметр будет использован для вычисления максимального размера буфера. При применении этого замечатльного алгоритма в плане запроса мы увидим Using join buffer (Batched Key Access). Более детальное освещение темы тут. Согласно результатам тестирования данная оптимизация может давать значительные ускорения только при условии ввода вывода и работы с диском. В этом случае вы можете получить 10-ти кратное ускорение только с MRR. В ряде других синтетических тестов были получены ускорения до 280 раз, при совместном использовании MRR и BKA. При работе же исключительно с памятью, ускорения вы не получите, что вполне логично, так как данная операция призвана оптимизировать исключительно ввод вывод.
File Sort Optimization — сортировка по неиндексированной колонке стала значительно более производительна, при соблюдении некоторых условий. Раньше при выполнении данного вида сортировки единственно возможным вариантом была сортировка слиянием. Грубо говоря, данные полученные в результате запроса сохранялись во временную таблицу. После этого для данной таблицы производилась сортировка и возвращались записи удовлетворяющие условию LIMIT. Как видно данный алгоритм не очень производителен, особенно если у вас много запросов, возвращающих малое количество строк. Для того чтобы оптимизировать ввод вывод алгоритм был изменен на следующий. Если количество записей полученных в результате выполнения запроса полностью помещается в sort_buffer_size, при сканировании таблицы создается очередь. Данная очередь является упорядоченной, и заполняется сразу в момент получения очередной строки результата запроса. Размер очереди N (или M + N если использована конструкция LIMIT M, N). При переполнении очереди лишние данные с конца выкидываются. Таким образом окончание сортировки производится одновременно с окончанием результата запроса, и полностью отсуствуют обращения ко временной таблице. Оптимизатор самостоятельно выбирает стратегию для проведения сортировки. Очередь будет использовна в том случае, когда необходимо больше загрузить процессор, сортировка слиянием когда доступна система ввода вывода.
При проведении синтетических тестов было получено ускорение в 4 раза. Но так же необходимо понимать что данная оптимизация позволяет снизить нагрузку на подсистему ввода вывода, что положительно скажется на работе всего инстанса.
Subqueries optimisation
postpone materialization — в основном она касается ускорения построения плана запроса. Ранее при выполнении команды EXPLAIN подзапросы используемые в секции FROM материализовались для получения по ним статистических данных. Т.е. фактически производилось выполнение данных запросов на БД. Сейчас эта операция не производится, и получить план запроса стало возможно не нагружаю инстанс БД. Однако и время выполнения запросов так же может быть ускорено, к примеру если имеется 2 материализуемых представления в секции FROM и первое не вернуло ни одной записи то 2-ое не будет выполнено. Так же во время выполнения запроса, MySQL может самостоятельно проиндексировать полученную материализованную таблицу, если сочтет это необходимым.
semi-join transformation — полусоединение может быть использовано для получения данных только из одной таблицы, на основании данных другой таблицы, во всех БД классическим примером является конструкция EXISTS. Использования этой оптимизации стало возможно и для конструкции IN которая раньше работала из рук вон плохо. Для того чтобы применение этой оптимизации стало возможно необходимо чтобы подзапрос удовлетворял следующим условиям: отсутствие UNION, отсутствие GROUP BY и HAVING, отсутствие ORDER BY с ограничением LIMIT (по отдельности данные конструкции могут быть использованы). Так же необходимо чтобы количество подзапросов не превышало максимальное количество таблиц допустимое для JOIN, так как в противном случае MySQL не сможет переписать данный запрос. Оптимизация достигается через переписывание запроса в SEMI JOIN или же через представление подзапроса в качестве VIEW в конструкции FROM и использование оптимизаций для postpone materialization описанных выше. Дублирующие записи из финального результата удаляются следующими способами:

  • при помощи помещения уникальных результатов финального запроса во временную таблицу (Start temporary и End temporary в колонке плана Extra)
  • при помощи применения критерия “первый найденный” на этапе сканирования таблицы из подзапроса (FirstMatch(tbl_name) в колонке плана Extra)
  • при помощи применения оптимизации Loose Index Scan (LooseScan(m..n) где m и n — части ключа используемые для данной оптимизации)

При материализации и последующем индексировании подзапроса в колонке select_type плана запроса будет стоятьMATERIALIZED. Для понимания как именно был переписан запрос можно использовать стандартную команду EXPLAIN EXTENDED. Таким образом вы всегда поймете, как именно был переписан ваш запрос, и была ли применена оптимизация.
Как вы понимаете переписывание криво написанных запросов (раньше за такие запросы я бы оторвал руки, сейчас это стало простительным) может дать просто бешеный прирост производительности, так что проводить тесты на table pullout (вынос подзапроса из условия WHERE в условие FROM) практически лишено смысла, ибо и 1000-и кратный прирост производительности там будет не предел, однако если все ваши запросы написаны корректно, то можете не ждать чего-то экстраординарного от данного вида оптимизаций.
Статичная статистика для InnoDB
Наконец-то свершилось. Не знаю откуда, из GooglePercona или же из самого Oracle, но в MySQL появилась возможность исключить из построения плана запроса динамический семплинг. Теперь статистика по таблицам и индексам хранится в персистных таблицах. Данный метод сбора статистики включен по умолчанию. При обновление более 10% данных в таблице, статистика по ней пересобирается автоматически (конечно же это можно изменить). Так же сбор статистики можно запустить принудительно командой ANALYSE. Для принудительного сброса статистики, когда оптимизатор беспрецендентно тупит, можно вызвать команду FLUSH TABLE. Что именно собирается можно наглядно посмотреть в новых таблицахmysql.innodb_index_statsmysql.innodb_table_stats. Это конечно не продвинутые оракляные гистограммы, но прогресс на лицо. Теперь планы стали более стабильны с одной стороны, а с другой у администраторов БД появилось новое развлечение: подадай когда статистика в таблице стала неактуальна, найди время простоя, угадай объем семплинга и пересчитай её, тем более как следует из блога разработчиков, статистику можно менять ручками, путем прямых апдейтов. Так же хотелось бы заметить что у меня при проведении тестов, сборщик статистики, видимо работающий в фоновом потоке, не успевал обрабатывать данные. Статистика на протяжении долгого времени оставалась пустой, пока я не запускал её анализ вручную. Анализ статистики для конкретной партиции запустить невозможно по этому приходилось проводить анализ всей партиционированной таблицы, что конечно же не очень удобно. Такая же ситуация возникает если провести активный DML и положить базу. Данные будут — статистики нет. Но думаю это исключительные ситуации и штатной работе базы данных они мешать не будут.
В качестве вывода по оптимизатору считаю нелишним заметить, что оптимизатор Maria DB 5.5 по заключению специалистов является более навороченным, однако в версии MySQL 5.6 ряд аналогичных оптимизаций позволяет добиться более высокой производительности.

Больше мьютексов хороших и разных

Как всем хорошо известно MySQL не достаточно хорошо масштабируется на большое количество процессоров при большом количестве одновременно выполняемых транзакций. Причиной всему внутренние блокировки, в частности kernel mutex, а так же принципиальные проблемы при работе с памятью в многоядерной архитектуре. Kernel mutex удерживаемый на время копирования списка активных транзакций, был разделен на несколько мьютексов, для неблокирущих и блокирующий транзакций, блокировок, ожиданий блокировок и т.д. Так же была решена проблема false sharing’а, когда одно ядро подгружало необходимые ему неизменяемые данные а другое необходимые ему изменяемые в одном cacheline, и как результат данные для первого ядра все время вымывались из кэша. Теперь для ряда критических объектов введено выравнивание в 64 байта.
Согласно блогам разработчиков MySQL стал масштабироваться на 50% лучше для read only транзакций. А прирост производительности при увеличении количества активных сессий составил до 600% по сравнению с предыдущей версией. При проведении независимых нагрузочных тестов, до 16 одновременных сессий — скорость работы не изменилась, выше — до 100% для смешанных транзакций на чтение запись и до 300% для транзакций read-only.

Оптимизация сброса UNDO

Теперь стало возможно сбрасывать UNDO параллельно. Для этого необходимо выставить параметр innodb_purge_threads в значени больше 1. Экспериментировать с этим параметром на промышленной БД будет разумно только тем, кто параллельно удаляет много данных из партиционированных таблиц. Улучшения производительности для тех кто не использует партиционирование или использует партиции для причин отличных от параллельного DML, к примеру архивирование, при котором DML операции производятся только с одной партицией, не будет, так как при сбросе данных вы повисните на блокировке dict_index_t::lock. Для них рекомендуется, как и раньше, просто выделить сброс данных в один, отдельный от основного, поток.

Оптимизация сброса грязных блоков

Как известно сброс грязных блоков из памяти одно из самых проблемных мест для любой версионной базы данных. Сброс необходимой части блоков на диск может быть осуществлен либо главным InnoDB Master Thread, и тогда будут ждать все, или, как в основном и бывает фоновым потоком, команду на сброс которому подаст конкретная сессия, и тогда эта сессия зависнет на неопределенное время, а остальные сесси заблокированы не будут. Для избежания проблем как в первом так и во втором случае был создан отдельный тред названный page_cleaner. Детальную информацию чем занят данный поток можно посмотреть тут

select name, comment from information_schema.innodb_metrics where name like 'buffer_flush_%';

Теперь сброс блоков действительно стал выполняться асинхронно. Если вы решите поиграть параметрами сброса блоков рекомендую так же обратить внимание на новые параметры оптимизации LRU flush так как данные параметры, согласно заключению разработчиков MySQL, могут косвенно влиять друг на друга.

Сброс блоков был одаптирован под SSD диски. Эта туманная фраза обозначает следующее. Как мы знаем кэширование блоков происходит страницами. 64 страницы образуют экстент. Соседями приянто называть эти самые последовательные страницы в рамках одного экстента. Раньше InnoDB при изменении страниц пытался набрать целый экстент для сброса данных на диск для оптимизации ввода вывода, так как для HDD один мегабайт является оптимальным размером, что позволяет выполнить операцию за одно обращение к диску. Для SSD возможен размер сброса всего 4 килобайта, так что набирать что либо лишено смысла. В добавок сбрасывать неизмененные страницы тоже лишено смысла. Так что обладателям новомодного железа можно поиграть с параметром.
В качестве вывода не лишне было бы заметить результаты вот этого теста.
Нужно ли переходить на MySQL 5.6Нужно ли переходить на MySQL 5.6
Как видно из графиков при работе с кэшем новая версия с оптимизированным сбросом, проигрывает MySQL 4.0.30 (причины выбора столько древней версии мне не известны) при малом количестве сессий, зато показывает на порядок лучший результат при масштабировании.
Нужно ли переходить на MySQL 5.6Нужно ли переходить на MySQL 5.6
При работе же с файловой системой результаты не столько впечатляющие и обе версии иду ноздря в ноздрю и MySQL 5.6 местами даже проигрывает. Однако согласно заключению автора, при выходе 5.6.12, данный недостаток будет устранен, и производительность скакнет в 3 раза. Т.е. для тех у кого проблемы с большим вводом выводом и активный сброс буферов на диски, стоит подождать выхода следующей версии, будет вам счастье.

InnoDB: ALTER TABLE… ONLINE

Все дифирамбы данной технологии можно смело охарактеризовать двумя словами — банальная реклама. Согласно заявлениям разработчиков данная команда была переписана чуть более чем полностью однако получить от этого какие-то существенные преимущества у команды InnoDB-engine не вышло. В online выполняется всего лишь ограниченное число крайне редкий операций, да ещё и с ограничениями. Понять что операция прошла online очень легко. В результате выполнения запроса вы получите

Query OK, 0 rows affected

И так что же можно:

  • CREATE INDEX, DROP INDEX — все мы привыкли что выполнение данных команд, не выполняет полное копирование таблицы однако блокирует обновление данных в ней. Это связано с тем, что построение индекса ранее производилось непосредственно по таблице и обладало, на момент сортировки и слияния, полным набором данных, что позволяет создать максимально сбалансированное индексное дерево. Теперь же на момент создания индекса на таблицу вешается блокировка только на чтение. Новые данные поступающие или исчезающие из таблицы попадают в специальный лог файл, созданный по аналогии со структурой change buffer, размер файла регулируется переменнойinnodb-online-alter-log-max-size. После проведения сортировки и слияния (размер буфера сортировки регулируется переменной innodb-sort-buffer-size) данные для нового индекса балком флашаться в REDO логи, после чего производится докат залогированых изменений. Вуаля и индекс доступен для использования. С одной стороны это не блокирует таблицу, с другой структура созданного индекса будет не настолько идеальна как в первом случае, да и его создание в случае активного DML таблицы может сильно затянуться, но это конечно же мелочи.
  • Изменение auto-increment значения для таблицы — несомненно полезно для тех пользователей, кто использует самописный шардинг производящий разделение данных по инстансам на основании значения первичного ключа.
  • DROP FOREIGN KEY — только удаление, добавление констрейнта пока не осилили, но в качестве бонуса разрешили удалять констрейнт и связанный с ним индекс одной коммандой.
    ALTER TABLE table DROP FOREIGN KEY constraint, DROP INDEX index;
  • Переименование колонки — online возможен только если не производится изменение типа данных. Изменяются только данные словаря. Опять же в качестве бонуса разрешили переименовывать колоки являющиеся частью внешнего ключа.

Ну вот собственно и все. Как видно из описания возможности предоставленные нам крайне скудны, будем надеяться, что в будущем ситуация улучшиться и изменения больших таблиц можно будет проводить без танцев с бубном, которые связаны с полным копированием таблицы при выполнении любой (с MySQL 5.6 читаем любой за исключением 5-ти) DDLкоманды.

Партиционирование

Был существенно переработан партиционный движок. Теперь выбор партиций на обработку выполняется раньше чем открытие таблиц и установка блокировок. Вот анализ ввода вывода при тривиальном запросе по партиционному ключу.

select count(1)
  from part_table
 where partition_key = 190110;
+----------+
| count(1) |
+----------+
|      500 |
+----------+
1 row in set (0.50 sec)

Ввод вывод и пул буферов

select   count(distinct file_name) file_name_count,
         sum(sum_number_of_bytes_read) sum_number_of_bytes_read,
         min(substring_index(file_name, '/', -1)) min_file_name,
         max(substring_index(file_name, '/', -1)) max_file_name
    from performance_schema.file_summary_by_instance
   where file_name like '%part_table%.ibd' and count_read + count_write > 0
order by 1;
-- Server version: 5.5
+-----------------+--------------------------+------------------------------------+------------------------------------+
| file_name_count | sum_number_of_bytes_read | min_file_name                      | max_file_name                      |
+-----------------+--------------------------+------------------------------------+------------------------------------+
|            1024 |                107692032 | part_table#P#part_table_184609.ibd | part_table#P#part_table_190110.ibd |
+-----------------+--------------------------+------------------------------------+------------------------------------+
-- Server version: 5.6
+-----------------+--------------------------+------------------------------------+------------------------------------+
|               1 |                    98304 | part_table#P#part_table_190110.ibd | part_table#P#part_table_190110.ibd |
+-----------------+--------------------------+------------------------------------+------------------------------------+

select min(table_name) min_table_name,
       max(table_name) max_table_name,
       count(distinct table_name) file_name_count,
       sum(data_size) pool_size
  from information_schema.innodb_buffer_page
 where table_name like '%part_table%';
-- Server version: 5.5
+--------------------------------------+--------------------------------------+-----------------+-----------+
| min_table_name                       | max_table_name                       | file_name_count | pool_size |
+--------------------------------------+--------------------------------------+-----------------+-----------+
| test/part_table#P#part_table_184609  | test/part_table#P#part_table_190110  |            1024 |  26567424 |
+--------------------------------------+--------------------------------------+-----------------+-----------+
-- Server version: 5.6
+--------------------------------------+--------------------------------------+-----------------+-----------+
| Partition `part_table_190110`        | Partition `part_table_190110`        |               1 |     32048 |
+--------------------------------------+--------------------------------------+-----------------+-----------+

Как видно в отличии от версии 5.5 статистика анализируется не по всем партициям указанной таблицы, а только по той которая соответствует условию. Что исключает подгрузку остальных партиций в буферный пул.

По блокировкам ничего пока не понятно, так как очень сильно поменялся сам алгоритм парсинга и ожидания выполнения запроса, из того что бросается в глаза, самый горячий мьютекс wait/synch/mutex/mysys/THR_LOCK::mutex ранее блокируемый для каждой партиции стал использоваться гораздо реже, т.е. при запросе по одной партиции он блокируется не столько раз сколько всего партиций в данной таблице умножить на два, а всего один, что несомненно большой плюс. Других блокировок с похожим агрессивным поведением мне найти пока не удалось. Судя по всему проблемы движка указанные в посте были устранены (для получения списка партиций, без самостоятельного их ведения, можно использовать таблицу mysql.innodb_table_stats, запись в нее добавляется в момент создания партиции, реальна статистика появляется позднее). Так же из приятного можно отметить повышение ограничения на максимально возможное количество партиций для одной таблицы. Так как нареканий к движку, лично у меня, больше не осталось, не лишне заметить, что партиции созданы для параллельной обработки, ждем hint parallel(n) для партиционированных таблиц.

Архивирование и восстановление

В новой версии было добавлено сразу две очень ожидаемые фичи для InnoDB:
EXCHANGE PARTITION

ALTER TABLE part_table EXCHANGE PARTITION p1 WITH TABLE non_part_table;

Все стандартно: таблицы должны иметь полностью идентичную структуру, включая индексы и storage engine, так же необходимо чтобы данные в непартиционированной таблице не выходили за пределы обмениваемой партиции.

Transportable Tablespaces
Как вы знаете просто так подменить .ibd файл и ожидать что у вас появятся данные — не прокатит. Так как необходимо учесть: REDO логи, словарь данных, системные колонки, метаданные табличного пространства и наверное ещё много чего. Для таких манипуляций теперь предусмотрено ряд комманд:
на БД экспорта
— FLUSH TABLES table_one, table_two FOR EXPORT;
— копируем .ibd и сгенерированный файл конфигурации из директории БД
на БД импорта
— создаем пустую таблицу аналогичной структуры
— ALTER TABLE table_one DISCARD TABLESPACE;
— копируем .ibd и сгенерированный файл конфигурации в директорию БД
— ALTER TABLE table_one IMPORT TABLESPACE;
Операции выполняется за счет словаря данных, а значит максимально быстро.

Performance Schema

Схемы диагностики производительности была заметно улучшена. Во первых её работа стала в три раза быстрее, т.е. просадка производительности при её включении теперь составляет не 10% а всего 3.5%, что позволило делать её включенной по умолчанию. По мимо этого теперь в схеме не 17 таблиц как ранее, а 52. Изменений как вы понимаете очень много, и если описывать их всех потребуется отдельная статья, по этому выделю лишь ключевые, по моему мнению, полезности откинув настройку и введение.

  • стало можно трейсить непосредственно запросы
    show tables like '%statements%';
    +----------------------------------------------------+
    | Tables_in_performance_schema (%statements%)        |
    +----------------------------------------------------+
    | events_statements_current                          |
    | events_statements_history                          |
    | events_statements_history_long                     |
    | events_statements_summary_by_account_by_event_name |
    | events_statements_summary_by_digest                |
    | events_statements_summary_by_host_by_event_name    |
    | events_statements_summary_by_thread_by_event_name  |
    | events_statements_summary_by_user_by_event_name    |
    | events_statements_summary_global_by_event_name     |
    +----------------------------------------------------+
    9 rows in set (0.01 sec)

     

  • трассировка выполняется на уровне строк как для постоянных таблиц так и для временных (хотя у меня почему то объектов с object_type= 'TEMPORARY TABLE' в схемах нет, вероятно что-то не сумел настроить, но персистные таблицы все присутствуют)
    select digest_text, sum_rows_affected, sum_rows_sent, sum_rows_examined from events_statements_summary_by_digest;
    +---------------------------------------+-------------------+---------------+-------------------+
    | digest_text                           | sum_rows_affected | sum_rows_sent | sum_rows_examined |
    +---------------------------------------+-------------------+---------------+-------------------+
    | SHOW VARIABLES                        |                 0 |          4410 |              4410 |
    ...
    | SET NAMES utf8                        |                 0 |             0 |                 0 |
    +---------------------------------------+-------------------+---------------+-------------------+
    48 rows in set (0.00 sec)

     

  • ожидания можно смотреть целиком по всей сессии
    show tables like '%by_thread%';
    +---------------------------------------------------+
    | Tables_in_performance_schema (%by_thread%)        |
    +---------------------------------------------------+
    | events_stages_summary_by_thread_by_event_name     |
    | events_statements_summary_by_thread_by_event_name |
    | events_waits_summary_by_thread_by_event_name      |
    +---------------------------------------------------+
    3 rows in set (0.00 sec)

     

  • можно мониторить временные таблицы, при чем как их создание в оперативной памяти, так и на диске, что позволит найти наиболее затратные запросы и выставить для них параметры сессии индивидуально
    select digest_text, sum_created_tmp_disk_tables, sum_created_tmp_tables from events_statements_summary_by_digest;
    +--------------------------------------------------------+-----------------------------+------------------------+
    | digest_text                                            | sum_created_tmp_disk_tables | sum_created_tmp_tables |
    +--------------------------------------------------------+-----------------------------+------------------------+
    | SHOW VARIABLES                                         |                           0 |                     10 |
    ...
    | SELECT `routine_schema` , `specific_name` FROM INF...  |                           2 |                      2 |
    ...
    | SHOW TABLE STATUS FROM `performance_schema` LIKE       |                           0 |                     52 |
    +--------------------------------------------------------+-----------------------------+------------------------+
    49 rows in set (0.00 sec)

     

  • больше конкретики, данные привели в удобоваримый вид, схема стала понятнее и проще
    show tables like 'table%waits%sum%';
    +-------------------------------------------------+
    | Tables_in_performance_schema (table%waits%sum%) |
    +-------------------------------------------------+
    | table_io_waits_summary_by_index_usage           |
    | table_io_waits_summary_by_table                 |
    | table_lock_waits_summary_by_table               |
    +-------------------------------------------------+
    3 rows in set (0.01 sec)

     

Для заинтересовавшихся могу порекомендовать вот это, думаю вебинар будет полезен как для начинающих, так и для знакомых с этой схемой с версии 5.5, так как изменений очень много. Так же от себя добавлю, что, так как схема теперь включена по умолчанию её настройки очень скромны. К примеру в основной таблице для 5.5 events_waits_history_longвсего 100 записей, а так как все эти параметры статические и их изменение требует перезапуск инстанса, то лучше заранее определится с вашими настройками.

Заключение

В качестве заключения позволю себе привести вывод Петра Зайцева озвученный в его недавней статье. По итогам синтетических тестов MySQL 5.6 медленнее предыдущей версии MySQL 5.5 на 7.5-11 процентов при нагрузке в один поток и на 11-26 процентов при нагрузке в 64 потока, что в корне разнится с официальной версией. Т.е. все переписали оптимально, но получить прирост производительности не смогли. При всех оптимизациях озвученных выше, вывод просто феноменален, но конечно же вам лучше проверить вашу среду самостоятельно. К примеру для нас критическим местом является вызов процедур. Для этого мы пользуемся самописным открытым фреймворком, из разработчиков на хабре присутствует esinevjbdc-proc. Замер попугаев выглядит следующим образом.
Нужно ли переходить на MySQL 5.6
Как видно прирост производительности на наших серверах мы не получаем, даже наоборот наблюдается падение попугаев до 20%, однако, устанавливая новую версию, мы получаем большое количество средств диагностики, которые позволят нам легче находить узкие места. Помимо этого уже сейчас понятно что MySQL идет в верном направлении, и подождав пару версий, чтобы убедиться в стабильности, мы планируем подъем версии.