Почему этот запрос занимает так много времени?

#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. Некоторая комбинация этих полей должна помочь.