Оптимизация MySQL сервера. Часть 5. Полезные запросы для MySQL

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

По мере нахождения полезных запросов я буду дополнять материал публикации.

Эта публикация сугубо мой конспект прочитанной литературы. Информация может быть не очень структурирована и удобочитаема. Материал публикации предоставляется без каких-либо гарантий со стороны автора.

Список первоисточников

  1. O’Reilly High Performance MySQL 3rd Edition.
  2. O’Reilly High Performance MySQL 4rd Edition.

Примеры запросов

Все те запросы, которые я посчитал полезными приведены в подразделах ниже.

Вывод запросов, которые не используют индекс

Запрос:

SELECT THREAD_ID, SQL_TEXT, ROWS_SENT, ROWS_EXAMINED, CREATED_TMP_TABLES,
NO_INDEX_USED, NO_GOOD_INDEX_USED
FROM performance_schema.events_statements_history_long
WHERE NO_INDEX_USED > 0 OR NO_GOOD_INDEX_USED > 0;

Вывод запросов, которые создают временные таблицы

Запрос:

SELECT THREAD_ID, SQL_TEXT, ROWS_SENT, ROWS_EXAMINED, CREATED_TMP_TABLES,
CREATED_TMP_DISK_TABLES
FROM performance_schema.events_statements_history_long
WHERE CREATED_TMP_TABLES > 0 OR CREATED_TMP_DISK_TABLES > 0;

Запросы, которые выполняются более 5 секунд

Запрос:

SELECT THREAD_ID, SQL_TEXT, ROWS_SENT, ROWS_EXAMINED, CREATED_TMP_TABLES,
CREATED_TMP_DISK_TABLES
FROM performance_schema.events_statements_history_long
WHERE TIMER_WAIT > 5000000000;

Потенциально проблемные запросы:

Запрос:

SELECT THREAD_ID, SQL_TEXT, ROWS_SENT, ROWS_EXAMINED, CREATED_TMP_TABLES,
CREATED_TMP_DISK_TABLES
FROM performance_schema.events_statements_history_long
WHERE ROWS_EXAMINED > ROWS_SENT
OR ROWS_EXAMINED > ROWS_AFFECTED
OR ERRORS > 0
OR CREATED_TMP_DISK_TABLES > 0
OR CREATED_TMP_TABLES > 0
OR SELECT_FULL_JOIN > 0
OR SELECT_FULL_RANGE_JOIN > 0
OR SELECT_RANGE > 0
OR SELECT_RANGE_CHECK > 0
OR SELECT_SCAN > 0
OR SORT_MERGE_PASSES > 0
OR SORT_RANGE > 0
OR SORT_ROWS > 0
OR SORT_SCAN > 0
OR NO_INDEX_USED > 0
OR NO_GOOD_INDEX_USED > 0;

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

КолонкаОписаниеВажность
CREATED_TMP_DISK_TABLESКоличество создаваемых запросом временных таблиц на диске. Вариантов решения два: либо оптимизировать запрос, либо увеличивать размер временных таблиц в памяти (параметры tmp_table_size и max_heap_table_size)Высокая
CREATED_TMP_TABLESКоличество создаваемых временных таблиц в оперативной памяти. Это не плохо само по себе. До тех пор, пока не превышен размер в параметрах tmp_table_size и max_heap_table_size. После этого начнется выгрузка на диск. И это уже проблема.Средняя
SELECT_FULL_JOINПолное сканирование таблицы при операциях JOIN говорит о том, что не хватает каких-то индексов. Нужно выяснять – каких именно.Высокая
SELECT_FULL_RANGE_JOINЭтот счетки для запроса увеличивается в том случае, если используется сканирование диапазона в операциях JOIN.Средняя
SELECT_RANGEОперация JOIN использует сканирование диапазова в первой таблице. Обычно это не проблема.Низкая
SELECT_RANGE_CHECKСчетчик увеличивается, если операция JOIN выполняется без использования индексов. Это очень плохой знак.Высокая
SELECT_SCANЕсли операция JOIN использует полное сканирование первой таблицы. Это не плохо, если размер таблицы небольшой.Средняя
SORT_MERGE_PASSESКоличество операций слияния, которые были выполнены при операции сортировки. Если запрос с использование операции сортировки выполняется медленно, то стоит увеличить параметр sort_buffer_sizeНизкая
SORT_RANGEПри выполнении операции сортировки использовался диапазонНизкая
SORT_ROWSКоличество строк в запросе на сортировки. Сравнивается с количество возвращаемых строк. Если количество сортируемых строк больше, чем количество возвращаемых строок, то нужно оптимизировать запросСредняя
SORT_SCANСчетчик увеличивается, если операция сортировки была выполнена с использованием сканирования таблицы.Высокая
NO_INDEX_USEDПри выполнении запроса не был использовал ни один индексВысокая (если таблица большая)
NO_GOOD_INDEX_USEDПри выполнении запроса использовался не оптимальный индекс. Необходимо провести ревизию имеющихся индексовВысокая

Запросы, которые используют полное сканирование таблицы

Запрос:

SELECT query, total_latency, no_index_used_count, rows_sent,
rows_examined
FROM sys.statements_with_full_table_scans
WHERE db='employees' AND
query NOT LIKE '%performance_schema%'\G

Запросы к sys schema

Запрос, которые выводит все проблемные или завершившиеся с ошибками запросы (обращение к sys.statements_with_errors_or_warnings):

SELECT query
FROM sys.statements_with_errors_or_warnings
WHERE db='employees' AND
query NOT LIKE '%performance_schema%'\G

Привести пример таблицы со страницы 57 новой книги от 2021 года.

Вы так же можете обращаться к другим представлениям sys:

ПредставлениеОписание
statement_analysisПредставление с агрегированной статистикой запросов, упорядоченное времени выполнения.
statements_with_errors_or_warningsВсе запросы, которые завершились с ошибками или предупреждениями
statements_with_full_table_scansВсе запросы, которые использовали полное сканирование таблицы
statements_with_runtimes_in_95th_percentileВсе запросы, время выполнения которые было больше, чем время выполнения 95% всех запросов. Короче говоря – список кандидатов на оптимизацию.
statements_with_sortingСписок запросов, которые использовали операцию(и) сортировки
statements_with_temp_tablesПеречень запросов, которые использовали временные таблицы

Полный перечень запросов к sys приведен в разделе документации по MySQL.

Статистика распределения типов запросов

Запрос

SELECT EVENT_NAME, COUNT(EVENT_NAME)
FROM events_statements_history_long
GROUP BY EVENT_NAME;

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

Запрос:

SELECT EVENT_NAME, COUNT(EVENT_NAME),
SUM(LOCK_TIME/1000000) AS latency_ms
FROM events_statements_history
GROUP BY EVENT_NAME ORDER BY latency_ms DESC;

Структуры InnoDB, которые используют больше всего памяти

Запрос:

SELECT EVENT_NAME,
CURRENT_NUMBER_OF_BYTES_USED/1024/1024 AS CURRENT_MB,
HIGH_NUMBER_OF_BYTES_USED/1024/1024 AS HIGH_MB
FROM performance_schema.memory_summary_global_by_event_name
WHERE EVENT_NAME LIKE 'memory/innodb/%'
ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC LIMIT 10;

Неиспользуемые индексы

Запрос:

SELECT * FROM sys.schema_unused_indexes;

Ссылки на другие статьи этого цикла

Часть 1. Тестирование производительности MySQL.

Часть 2. Профилирование нагрузки сервера MySQL.

Часть 3. Базовая конфигурация и оптимизация настроек MySQL.

Часть 4. Признаки проблем с производительностью MySQL.

Часть 6. Нюансы настройки репликации MySQL.

Часть 7. Резервное копирование MySQL.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *