Статьи

Расширенная настройка MySQL Query: продолжение вебинара Q & A


Этот пост принадлежит 
Александру Рубину из блога MySQL Performance.

Спасибо всем, кто посетил мой вебинар « Настройка MySQL Query » 24 июля. Если вы пропустили его, вы можете скачать слайды, а также посмотреть записанное видео . Спасибо за отличные вопросы и после вебинара. Настройка запросов — большая тема, и из-за ограниченного времени мне пришлось пропустить некоторые материалы, особенно часть мониторинга. Я хотел бы, однако, ответить на все вопросы, которые я не задавал во время сессии вебинара.

Вопрос: Сбрасывали ли вы кеш запросов, прежде чем выполнить тест по вашему запросу? 0,00 секунды звучит слишком хорошо 

A:  (Это в ответ на пару слайдов, где время показывается как 0,00). Да, MySQL работал с отключенным кешем запросов. Значение 0,00 означает, что запрос был выполнен менее чем за 0,004 секунды. MySQL не показывает более высокую точность, если вы запускаете запрос из монитора MySQL. Есть несколько способов получить точное время запроса:

  • MySQL 5.0 +: используйте функцию «профилирования»: http://dev.mysql.com/doc/refman/5.5/en/show-profile.html
  • MySQL 5.1 +: включите медленный журнал запросов с точностью до микросекунды и зарегистрируйте запрос. Для регистрации всех запросов в журнале медленных запросов вы можете временно установить: long_query_time = 0
  • MySQL 5.6: используйте новые счетчики performance_schema

Вот профиль для примера запроса, запрос показывает 0,00 секунд:

mysql> show profile;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000064 |
| checking permissions | 0.000003 |
| checking permissions | 0.000006 |
| Opening tables | 0.000019 |
| System lock | 0.000011 |
| init | 0.000031 |
| optimizing | 0.000011 |
| statistics | 0.000014 |
| preparing | 0.000011 |
| executing | 0.000002 |
| Sending data | 0.002161 |
| end | 0.000004 |
| query end | 0.000002 |
| closing tables | 0.000007 |
| freeing items | 0.000012 |
| logging slow query | 0.000001 |
| cleaning up | 0.000002 |
+----------------------+----------+

Как мы видим, отправка данных на самом деле составляет 0,002 секунды.

Вопрос: Видели ли вы когда-нибудь семинар, на котором показано, как использовать распараллеливание (openCL или CUDA) с базами данных и различия в производительности?

A:  MySQL не поддерживает это прямо сейчас. Обычно openCL / CUDA не помогает в приложениях, связанных с диском, таких как базы данных. Однако некоторые проекты в пространстве OLAP могут фактически использовать openCL / CUDA, например, Alenka , это хранилище столбцов, которое является массивно параллельным. Сканирование, агрегация, сортировка и т. Д. Выполняются в виде потока данных посредством обработки CUDA.

 В: Можно ли использовать этот / покрытый индекс для заказа по — AR / с соединением? Например, если мы хотим использовать где в таблице A и сортировать его по столбцу из таблицы B

A: К сожалению, MySQL не поддерживает это с покрытым индексом. MySQL будет использовать фильтр только для условия where (для ограничения количества строк) + файловой сортировки. Однако, если у нас есть предложение limit, MySQL может использовать индекс для упорядочения и остановки после нахождения N строк, соответствующих условию. Это может быть не так быстро, как вы (как я показал во время вебинара), и вам, возможно, придется использовать подсказки индекса, чтобы сказать MySQL использовать точный индекс (возможно, это не лучший подход, так как в некоторых случаях использование этого индекса может не лучшее для этого случая). Пример:

mysql> explain select * from City ct join Country cn on (ct.CountryCode = cn.Code) where Continent = 'North America' order by ct.population desc limit 10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ct
type: index
possible_keys: NULL
key: Population
key_len: 4
ref: NULL
rows: 10
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: cn
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 3
ref: world.ct.CountryCode
rows: 1
Extra: Using where

Как мы видим, MySQL будет использовать index и избегать «order by».

В: Почему хеш-индексы недоступны для движка InnoDB? Есть планы занести хеш-индексы.

A:  InnoDB использует хэш-индексы для так называемой « адаптивной хэш-индекса ». InnoDB не поддерживает хеш-индексы как обычный табличный индекс. Нам неизвестно о планах Oracle по внедрению InnoDB.

Обратите внимание: MySQL позволит вам использовать ключевое слово «using hash» при создании индекса для таблицы InnoDB. Однако вместо этого он создаст индекс b-дерева.

Q: Замедляют ли ограничения внешнего ключа мои запросы?

A: Это может замедлить запросы, так как InnoDB придется

  1. Проверьте таблицу ограничений внешнего ключа
  2. Поместите разделяемую блокировку в строку, которая будет читать: 

Если в  FOREIGN KEY таблице определено ограничение, то при любом вставке, обновлении или удалении, требующем проверки условия ограничения, устанавливаются общие блокировки на уровне записей для записей, которые он просматривает для проверки ограничения. InnoDB также устанавливает эти блокировки в случае, когда ограничение не выполняется. ( http://dev.mysql.com/doc/refman/5.5/en/innodb-locks-set.html )

Вопрос: Как использование индекса зависит от количества столбцов, выбранных в запросе выбора?

Если мы говорим о покрытом индексе: если мы выберем столбец, который не является частью покрытого индекса, mysql не сможет удовлетворить запрос только по индексу («используя индекс» в плане объяснения). Это может быть медленнее, особенно если MySQL придется выбирать большие столбцы, а данные не кэшируются.

Кроме того, если мы выберем столбец text или blob и MySQL потребуется создать временную таблицу, эта временная таблица будет создана на диске. Я описал этот сценарий во время вебинара.