Size: a a a

2020 May 23

VS

Viktor Sh in ru_mysql
Вот так выглядит инфо по таблице:
источник

VS

Viktor Sh in ru_mysql
источник

VS

Viktor Sh in ru_mysql
Это с категориями:
источник

VS

Viktor Sh in ru_mysql
Если убрать SQL_CALC_FOUND_ROWS, то получается вот так:
источник

VS

Viktor Sh in ru_mysql
# Time: 2020-05-22T22:33:34.159395Z
# User@Host: cs_user[cs_user] @ localhost []  Id:   309
# Schema: cs_komfort  Last_errno: 0  Killed: 0
# Query_time: 8.462233  Lock_time: 0.000783  Rows_sent: 0  Rows_examined: 1280210  Rows_affected: 0
# Bytes_sent: 539
SET timestamp=1590186805;
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, 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'  LEFT 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' LEFT JOIN cscart_discussion ON cscart_discussion.object_id = products.product_id AND cscart_discussion.object_type = 'P' LEFT JOIN cscart_discussion_posts ON cscart_discussion_posts.thread_id = cscart_discussion.thread_id AND cscart_discussion_posts.status = 'A' LEFT 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
Всёравно 8 секунд
источник

VS

Viktor Sh in ru_mysql
Таких запросов на страницу карточки товара выполняется 5 штук и все немного разные
источник

VS

Viktor Sh in ru_mysql
Так как блоки чуток отличаются друг от друга:
1) Хиты продаж
2) С этим товаром покупают
3) Похожие товары
4) Самые популярные
5) Недавно просмотренные
источник

E

Eugene in ru_mysql
ругается на cscart_categories
источник

E

Eugene in ru_mysql
там у вас FIND_IN_SET
источник

E

Eugene in ru_mysql
попробуйте без него
источник

А

Александр in ru_mysql
Viktor Sh
# Time: 2020-05-22T22:33:34.159395Z
# User@Host: cs_user[cs_user] @ localhost []  Id:   309
# Schema: cs_komfort  Last_errno: 0  Killed: 0
# Query_time: 8.462233  Lock_time: 0.000783  Rows_sent: 0  Rows_examined: 1280210  Rows_affected: 0
# Bytes_sent: 539
SET timestamp=1590186805;
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, 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'  LEFT 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' LEFT JOIN cscart_discussion ON cscart_discussion.object_id = products.product_id AND cscart_discussion.object_type = 'P' LEFT JOIN cscart_discussion_posts ON cscart_discussion_posts.thread_id = cscart_discussion.thread_id AND cscart_discussion_posts.status = 'A' LEFT 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;
Убрирание SQL_CALC_FOUND_ROWS никак не влияет на данный запрос, т.к. у нас есть GROUP BY и вё равно сканятся все таблицы полностью чтобы получить 10 строк
источник

А

Александр in ru_mysql
данный запрос легко ускорить до 10мс
источник

А

Александр in ru_mysql
надо переписать на скалярные запросы и убрать GROUP BY
SQL_CALC_FOUND_ROWS оставить выкинутым, пагинацию делать не считая все строки, а получать 10 + 1 строку как индикатор наличия следующей страницы, всё будет летать
источник

А

Александр in ru_mysql
никакие редисы и прочие костыли не нужны, настройки тож дефолтные пойдут, их ковырять не надо, задача тривиальна
источник

VS

Viktor Sh in ru_mysql
Александр
надо переписать на скалярные запросы и убрать GROUP BY
SQL_CALC_FOUND_ROWS оставить выкинутым, пагинацию делать не считая все строки, а получать 10 + 1 строку как индикатор наличия следующей страницы, всё будет летать
Да, запросы не оптимизированы, но на MySQL 5.6 они летают, а тут зачем то 8-ку поставили и всё колом стоит :(
источник

А

Александр in ru_mysql
бегло и невнимательно запрос посмотрел, тут не пройдут скалярные запросы..., т.к. у нас ограничение на агрегацию
HAVING average_rating > 0
и ещё сортировка по average_rating
т.е. чтобы фильтрануть по average_rating, надо всё равно все таблицы соединить и все данные извлечь
источник

А

Александр in ru_mysql
сколько ~ записей в cscart_products
источник

А

Александр in ru_mysql
?
источник

VS

Viktor Sh in ru_mysql
180 тыс примерно
источник