hosting:mysql:query-optimization

Различия

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

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
hosting:mysql:query-optimization [2019/08/28 17:28]
karlov
hosting:mysql:query-optimization [2020/04/24 13:42]
zinenko
Строка 20: Строка 20:
 </code> </code>
  
-Если запрос выполнить с условием ''EXPLAIN'' в начале, то получим схему выполнения запроса:+ Если запрос выполнить с условием ''EXPLAIN'' в начале, то получим схему выполнения запроса:  
 +<panel type="default" no-body="true">
  
 ^ Тип выборки ^ Таблица ^ Тип ^ Возможные ключи ^ Ключ ^ Длина ключа ^ Ссылка ^ Строки ^ Доп. информация ^ ^ Тип выборки ^ Таблица ^ Тип ^ Возможные ключи ^ Ключ ^ Длина ключа ^ Ссылка ^ Строки ^ Доп. информация ^
 | PRIMARY | p | ALL | PRIMARY |  |  |  |  2907 | Using where;\\ Using filesort | | PRIMARY | p | ALL | PRIMARY |  |  |  |  2907 | Using where;\\ Using filesort |
-| PRIMARY | pd | eq_ref | PRIMARY | PRIMARY |  8 | mebelnyc_db.p.product_id,const |  1 | Using where;\\ Using index | +| PRIMARY | pd | eq_ref | PRIMARY | PRIMARY |  8 | mebelnyc_db.p.product_id, const |  1 | Using where;\\ Using index | 
-| PRIMARY | p2s | eq_ref | PRIMARY | PRIMARY |  8 | mebelnyc_db.p.product_id,const |  1 | Using where;\\ Using index |+| PRIMARY | p2s | eq_ref | PRIMARY | PRIMARY |  8 | mebelnyc_db.p.product_id, const |  1 | Using where;\\ Using index |
 | DEPENDENT SUBQUERY | pt | ALL |  |  |  |  |  6803 | Using where | | DEPENDENT SUBQUERY | pt | ALL |  |  |  |  |  6803 | Using where |
 | DEPENDENT SUBQUERY | r1 | ref | product_id | product_id |  4 | mebelnyc_db.p.product_id |  1 | Using where | | DEPENDENT SUBQUERY | r1 | ref | product_id | product_id |  4 | mebelnyc_db.p.product_id |  1 | Using where |
 +</panel>
   - Если убрать из этого запроса условие ''LIMIT'', то он вернёт 2907 записей. Именно 2907 раз будет выполнен вложенный в условие ''SELECT'' запрос. Если эту часть запроса вынести в отдельный запрос, то это уменьшит нагрузку на базу данных в 2907/20=145 раз. Хотя, судя по названию запроса, можно сделать вывод относительно того, что таким интересным способом автор программы пытается при каждом заходе посетителя на сайт считать статистику товаров, которая может пересчитываться, к примеру, раз в сутки или ещё лучше — при добавлении отзыва к товару и добавляться в отдельную колонку таблицы ''mc_product'', что позволит избавиться от этого вложенного запроса.   - Если убрать из этого запроса условие ''LIMIT'', то он вернёт 2907 записей. Именно 2907 раз будет выполнен вложенный в условие ''SELECT'' запрос. Если эту часть запроса вынести в отдельный запрос, то это уменьшит нагрузку на базу данных в 2907/20=145 раз. Хотя, судя по названию запроса, можно сделать вывод относительно того, что таким интересным способом автор программы пытается при каждом заходе посетителя на сайт считать статистику товаров, которая может пересчитываться, к примеру, раз в сутки или ещё лучше — при добавлении отзыва к товару и добавляться в отдельную колонку таблицы ''mc_product'', что позволит избавиться от этого вложенного запроса.
   - В условии ''WHERE'' мы видим вложенный запрос, который выполняется в условии ''IN''. Если бы автор программы в условии ''IN'' указал не вложенный запрос, а просто статические значения, например ''IN (121, 1235, 43554)'', то MySQL использовал бы индекс и отработал быстро. Но с вложенными запросами дело обстоит совсем по другому — MySQL выполняет их без использования индексов, а точнее так — ''FIN_IN_SET(p.product_id, '121,1235,43554')''. В таких случаях нужно писать запрос отдельно, а потом подставлять результат его выполнения в условие ''IN''.   - В условии ''WHERE'' мы видим вложенный запрос, который выполняется в условии ''IN''. Если бы автор программы в условии ''IN'' указал не вложенный запрос, а просто статические значения, например ''IN (121, 1235, 43554)'', то MySQL использовал бы индекс и отработал быстро. Но с вложенными запросами дело обстоит совсем по другому — MySQL выполняет их без использования индексов, а точнее так — ''FIN_IN_SET(p.product_id, '121,1235,43554')''. В таких случаях нужно писать запрос отдельно, а потом подставлять результат его выполнения в условие ''IN''.
- 
-===== Другие статьи ===== 
- 
-{{indexmenu>.#1|nsort tsort}} 
  • hosting/mysql/query-optimization.txt
  • Последнее изменение: 2020/04/24 13:42
  • zinenko