Добрый день. Проблема в том, что Mysql выбирает неудачный порядок соединения таблиц, через что ORDER BY не использует индекс, что влияет на производительность. Сам запрос
EXPLAIN
SELECT SQL_NO_CACHE
#STRAIGHT_JOIN
o.offer_id,o.name,o.price,o.updated,o.description,
`ogc`.general_category_id AS category_id , `gc`.name AS categoryName
FROM `offers` AS o
INNER JOIN `shops` AS s ON (o.shop_id = s.shop_id)
INNER JOIN `offers_general_categories` AS ogc ON ( o.offer_id = ogc.offer_id )
INNER JOIN `general_categories` AS gc ON ( gc.general_category_id = ogc.general_category_id )
WHERE o.deleted ='false' AND s.display_status ='on' AND o.shop_id IN (1,2)
AND o.price <= '10000' AND o.price >= '1500'
ORDER BY `updated` DESC
LIMIT 10, 10
Результат EXPLAIN*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: s
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 2
Extra: Using where; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: o
type: ref
possible_keys: PRIMARY,updating_shop_id,shop_id_price_deleted,shop_offers_shop,shop_id_deleted
key: shop_offers_shop
key_len: 4
ref: xml_debug.s.shop_id
rows: 2749
Extra: Using where
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: ogc
type: ref
possible_keys: general_category_id_offer_id,updating_offer_id,offer_id_offers_general_categories,general_category_id_offers_general_categories
key: general_category_id_offer_id
key_len: 8
ref: xml_debug.o.offer_id
rows: 1
Extra: Using index
*************************** 4. row ***************************
id: 1
select_type: SIMPLE
table: gc
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: xml_debug.ogc.general_category_id
rows: 1
Extra:
Как видно что порядок JOIN изменился и MYSQL использует Using temporary; Using filesort. Такой запрос выполняется за 0.38 s
Если же использовать STRAIGHT_JOIN тогда результат совершенно другой.
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: o
type: index
possible_keys: PRIMARY,updating_shop_id,shop_id_price_deleted,shop_offers_shop,shop_id_deleted
key: updated
key_len: 4
ref: NULL
rows: 66
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: s
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: xml_debug.o.shop_id
rows: 1
Extra: Using where
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: ogc
type: ref
possible_keys: general_category_id_offer_id,updating_offer_id,offer_id_offers_general_categories,general_category_id_offers_general_categories
key: general_category_id_offer_id
key_len: 8
ref: xml_debug.o.offer_id
rows: 1
Extra: Using index
*************************** 4. row ***************************
id: 1
select_type: SIMPLE
table: gc
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: xml_debug.ogc.general_category_id
rows: 1
Extra:
Время выполнения: 0.0033 s
В этом случае MYSQL использовал индекс updated для сортировки. Без Using temporary; Using filesort
Почему MYSQL так просчитывает, что можно предпринять?
Запрос используется для поиска, где параметры могут менятся и подключатся еще таблицы. Поэтому использование в запросе STRAIGHT_JOIN, только частичный случай.
Спасибо за внимание.