Size: a a a

2020 May 25

А

Александр in ru_mysql
В скобках не вижу
источник

А

Александр in ru_mysql
И сколько каждый запрос выполняется?
источник

А

Александр in ru_mysql
Александр
В скобках не вижу
А, вижу
источник

А

Александр in ru_mysql
Последний запрос явно ускоряется аналогичным образом
источник

А

Александр in ru_mysql
Лефт джоины заменяются на иннер
источник

А

Александр in ru_mysql
Остальные надо смотреть
источник

А

Александр in ru_mysql
Второй запрос также, соединение с cscart_product_popularity заменить на иннер джоин
источник

А

Александр in ru_mysql
Александр
Второй запрос также, соединение с cscart_product_popularity заменить на иннер джоин
3й аналогично
источник

А

Александр in ru_mysql
4й и так должен быстро работать
источник

А

Александр in ru_mysql
Александр
Последний запрос явно ускоряется аналогичным образом
5й запрос ☝️
источник

А

Александр in ru_mysql
1й, я так понял, показывает последние добавленные товары, если выпилить из него SQL_CALC_FOUND_ROWS, то тож можно ускорить раз в 100-200
источник
2020 May 26

А

Александр in ru_mysql
1.
- убираем ORDER BY products.timestamp desc
- оставляем ORDER BY products.product_id desc
- убираем SQL_CALC_FOUND_ROWS
- всякую побочку, которую не выбираем, а только ограничиваем по ней выносим в EXISTS
- избавляемся от GROUP BY

должно работать быстро
SELECT products.product_id,
   IF(shared_descr.product_id IS NOT NULL, shared_descr.product, descr1.product) as product,
   products.product_type,
   products.parent_product_id
FROM cscart_products as products -- (181 153)
LEFT JOIN
   cscart_product_descriptions as descr1 -- (174 225)
       ON descr1.product_id = products.product_id
           AND descr1.lang_code = 'ru'
LEFT JOIN
   cscart_ult_product_descriptions as shared_descr -- (175 810)
       ON shared_descr.product_id = products.product_id
           AND shared_descr.company_id = 1
           AND shared_descr.lang_code = 'ru'
WHERE 1
   AND (products.usergroup_ids = '' OR FIND_IN_SET(0, products.usergroup_ids) OR FIND_IN_SET(1, products.usergroup_ids))
   AND products.status IN ('A')
   AND products.parent_product_id = 0
   AND EXISTS (
       SELECT NULL
       FROM cscart_product_prices as prices -- (182 628)
       ON prices.product_id = products.product_id
           AND prices.lower_limit = 1
           AND prices.usergroup_id IN (0, 0, 1)
   )
   AND EXISTS (
       SELECT NULL
       FROM cscart_products_categories as products_categories -- (193 554)
       INNER JOIN
           cscart_categories -- (1218)
               ON cscart_categories.category_id = products_categories.category_id
                   AND (cscart_categories.usergroup_ids = '' OR FIND_IN_SET(0, cscart_categories.usergroup_ids) OR FIND_IN_SET(1,cscart_categories.usergroup_ids))
                   AND cscart_categories.status IN ('A', 'H')
       WHERE products_categories.product_id = products.product_id
           AND cscart_categories.company_id = 1
   )
ORDER BY products.product_id desc
LIMIT 0, 10;
источник

А

Александр in ru_mysql
2.
- тут достаточно заменить LEFT JOIN cscart_product_popularity, на INNER JOIN
- по идее можно ещё сделать как в первом запросе, перенести побочку в EXISTS и избавится от GROUP BY, но достаточно и первого пункта
SELECT
   SQL_CALC_FOUND_ROWS
   products.product_id,
   IF(shared_descr.product_id IS NOT NULL, shared_descr.product, descr1.product) as product,
   popularity.total as popularity,
   products.product_type,
   products.parent_product_id
FROM
   cscart_products as products
LEFT JOIN
   cscart_product_descriptions as descr1
       ON descr1.product_id = products.product_id
           AND descr1.lang_code = 'ru'
INNER JOIN
   cscart_product_prices as prices
       ON prices.product_id = products.product_id
           AND prices.lower_limit = 1
INNER JOIN
   cscart_products_categories as products_categories
       ON products_categories.product_id = products.product_id
INNER JOIN
   cscart_categories
       ON cscart_categories.category_id = products_categories.category_id
           AND (cscart_categories.usergroup_ids = '' OR FIND_IN_SET(0, cscart_categories.usergroup_ids) OR FIND_IN_SET(1,cscart_categories.usergroup_ids))
           AND cscart_categories.status IN ('A', 'H')
INNER JOIN
   cscart_product_popularity as popularity
       ON popularity.product_id = products.product_id
LEFT JOIN
   cscart_ult_product_descriptions shared_descr
       ON shared_descr.product_id = products.product_id
           AND shared_descr.company_id = 1
           AND shared_descr.lang_code = 'ru'
WHERE 1
   AND cscart_categories.company_id = 1
   AND popularity.total >= 1
   AND (products.usergroup_ids = '' OR FIND_IN_SET(0, products.usergroup_ids) OR FIND_IN_SET(1, products.usergroup_ids))
   AND products.status IN ('A')
   AND prices.usergroup_id IN (0, 0, 1)
   AND products.parent_product_id = 0
GROUP BY
   products.product_id
ORDER BY
   popularity.total desc,
   products.product_id ASC
LIMIT 0, 10;
источник

А

Александр in ru_mysql
3. повтор второго
источник

А

Александр in ru_mysql
4.
- тут уже всё должно работать быстро, запрос оптимизирован
источник

А

Александр in ru_mysql
5.
- заменяем соединения cscart_discussion, cscart_discussion_posts, cscart_discussion_rating на INNER JOIN
SELECT SQL_CALC_FOUND_ROWS products.product_id
, IF(shared_descr.product_id IS NOT NULL, shared_descr.product, descr1.product) as product
, products.product_type
, products.parent_product_id
, AVG(cscart_discussion_rating.rating_value) AS average_rating
, cscart_discussion.type AS discussion_type
, cscart_discussion.thread_id AS discussion_thread_id
FROM cscart_products as products
LEFT JOIN cscart_product_descriptions as descr1 ON descr1.product_id = products.product_id AND descr1.lang_code = 'ru'
INNER JOIN cscart_product_prices as prices ON prices.product_id = products.product_id AND prices.lower_limit = 1
INNER JOIN cscart_products_categories as products_categories ON products_categories.product_id = products.product_id
INNER JOIN cscart_categories ON cscart_categories.category_id = products_categories.category_id
AND (cscart_categories.usergroup_ids = '' OR FIND_IN_SET(0, cscart_categories.usergroup_ids) OR FIND_IN_SET(1, cscart_categories.usergroup_ids))
AND cscart_categories.status IN ('A', 'H')
LEFT JOIN cscart_ult_product_descriptions shared_descr ON shared_descr.product_id = products.product_id AND shared_descr.company_id = 1 AND shared_descr.lang_code = 'ru'
INNER JOIN cscart_discussion ON cscart_discussion.object_id = products.product_id AND cscart_discussion.object_type = 'P'
INNER JOIN cscart_discussion_posts ON cscart_discussion_posts.thread_id = cscart_discussion.thread_id AND cscart_discussion_posts.status = 'A'
INNER JOIN cscart_discussion_rating ON cscart_discussion.thread_id = cscart_discussion_rating.thread_id
AND cscart_discussion_rating.post_id = cscart_discussion_posts.post_id
AND cscart_discussion_rating.rating_value != 0
WHERE 1
AND cscart_categories.company_id = 1
AND (products.usergroup_ids = '' OR FIND_IN_SET(0, products.usergroup_ids) OR FIND_IN_SET(1, products.usergroup_ids))
AND products.status IN ('A')
AND prices.usergroup_id IN (0, 0, 1)
AND products.parent_product_id = 0
GROUP BY products.product_id
HAVING average_rating > 0
ORDER BY average_rating desc, products.product_id ASC
LIMIT 0, 10;
источник

VS

Viktor Sh in ru_mysql
Александр, спасибо большое, но тут самое долгое - это перемножение 170К на 170К строк, от него никуда не деться =(((
источник

VS

Viktor Sh in ru_mysql
Вот первый запрос, было - стало
источник

VS

Viktor Sh in ru_mysql
Я сейчас часть из этих блоков отключил совсем, часть переориентировал на категорийную фильтрацию, стало всё летать.
источник

А

Александр in ru_mysql
мускуль не будет извлекать все 170к строк, если убрать в первом запросе SQL_CALC_FOUND_ROWS
источник