#mysql #performance #explain
#mysql #Производительность #объясните
Вопрос:
Этот запрос появляется в моем медленном журнале в системе mysql,
# Query_time: 37 Lock_time: 0 Rows_sent: 5 Rows_examined: 405199
select euroapps.id, euroapps.name, euroapps.imageurl, euroapps.created,
application_price.retail_price, euroapps.count FROM application_price INNER JOIN
euroapps ON euroapps.id = application_price.application_id WHERE
application_price.storefront_id = '143441' AND application_price.retail_price <= 0
ORDER BY created DESC LIMIT 5;
Вы видите, что он проверяет 405 199 строк, может ли это быть причиной длительного времени запроса?
Подобный запрос никогда не отображается в моем журнале slow, этот запрос:
select euroapps.id, euroapps.name, euroapps.imageurl, euroapps.created,
application_price.retail_price, euroapps.count FROM application_price INNER JOIN
euroapps ON euroapps.id = application_price.application_id WHERE
application_price.storefront_id = '$store' AND application_price.retail_price > 0
ORDER BY created DESC LIMIT 5
Вот результат explain:
mysql> explain select euroapps.id, euroapps.name, euroapps.imageurl, euroapps.created, application_price.retail_price, euroapps.count FROM application_price INNER JOIN euroapps ON euroapps.id = application_price.application_id WHERE application_price.storefront_id = '143441' AND application_price.retail_price <= 0 ORDER BY created DESC LIMIT 5;
---- ------------- ------------------- -------- ---------------------------------- -------------------------- --------- --------------------------------------------- -------- -----------------------------------------------------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---- ------------- ------------------- -------- ---------------------------------- -------------------------- --------- --------------------------------------------- -------- -----------------------------------------------------------
| 1 | SIMPLE | application_price | range | PRIMARY,idx_storedfront_price_id | idx_storedfront_price_id | 9 | NULL | 110491 | Using where; Using index; Using temporary; Using filesort |
| 1 | SIMPLE | euroapps | eq_ref | PRIMARY | PRIMARY | 4 | itunesapps.application_price.application_id | 1 | |
---- ------------- ------------------- -------- ---------------------------------- -------------------------- --------- --------------------------------------------- -------- -----------------------------------------------------------
2 rows in set (0.00 sec)
Комментарии:
1. Если у вас их еще нет, я бы поставил индексы на
application_price.application_id
,application_price.storefront_id
иapplication_price.retail_price
.2. @Jason как раз писал то же самое :). Кроме того, каков тип данных
application_price.retail_price
столбца? Если значение может быть ниже нуля, убедитесь, что оно числовое и не беззнаковое3. Возможно, вы также захотите изменить настройки памяти MySQL. Я ДУМАЮ, хотя и не уверен, что «Использование temporary; Использование filesort» означает, что MySQL создает какой-то временный файл на жестком диске, чтобы выполнить его сортировку, тогда как потенциально он мог бы выполнять эту сортировку прямо в оперативной памяти, если бы конфигурация памяти позволяла ему это делать. Не цитируйте меня по этому поводу, но недавно у меня была похожая проблема, и увеличение объема доступной памяти устранило проблему.
4. Еще одна вещь, которая может помочь: убедитесь, что все столбцы, которые могут быть числовыми, являются числовыми. Я читал в высокопроизводительном MySQL, что индексы в числовых полях выполняются быстрее, чем в строковых, поскольку числовые значения, конечно, меньше строковых.
5. У меня есть индексы для application_price.application_id, application_price.storefront_id и application_price.retail_price Тип данных розничной цены — десятичный (9,2)
Ответ №1:
Вам следует взглянуть на план выполнения, который поможет сузить причину. http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html
Ответ №2:
Глядя на ваше предложение WHERE, вы можете видеть, что вы используете application_price.storefront_id
в качестве фактора фильтрации. Однако в вашем ОБЪЯСНЕНИИ он не отображается как возможный ключ, что означает, что он не проиндексирован, что означает, что требуется полное сканирование таблицы.
Другим фактором является то, что application_price.retail_price
вы можете видеть, что означает ДИАПАЗОН в explain — однако его мощность, по-видимому, невелика — отсюда и такое количество строк.
Как предложил Джейсон Свитт — проиндексируйте свой application_price.storefront_id, и вы увидите лучшую производительность (и, Джейсон, вам, вероятно, следует опубликовать свой комментарий в качестве ответа).
Ответ №3:
Столбец «строки» в объяснении указывает, что MySQL eastimates должен будет проверить 110491 строку из таблицы application_price. Также используется temporary; Используется filesort в этой таблице.
Я предлагаю вам добавить индекс для application_price, который включает (storefront_id, application_id, retail_price, создано), если «создано» — это поле application_price. Некоторая комбинация этих полей должна помочь.