Reputation: 484
I have a shopping cart that continually logs slow queries like this one...
# Query_time: 4 Lock_time: 0 Rows_sent: 50 Rows_examined: 454403
SELECT SQL_CALC_FOUND_ROWS products.*,
descr1.product AS product,
Min(prices.price) AS price,
GROUP_CONCAT(IF(products_categories.link_type = 'M',
Concat(products_categories.category_id,
'M'), products_categories.category_id)) AS
category_ids,
cscart_seo_names.name AS seo_name
FROM cscart_products AS products
LEFT JOIN cscart_product_descriptions AS descr1
ON descr1.product_id = products.product_id
AND descr1.lang_code = 'EN'
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_seo_names
ON cscart_seo_names.object_id = products.product_id
AND cscart_seo_names.TYPE = 'p'
AND cscart_seo_names.dispatch = ''
AND cscart_seo_names.lang_code = 'EN'
WHERE 1
AND products.company_id = 0
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 )
GROUP BY products.product_id
ORDER BY descr1.product ASC
LIMIT 1300, 50;
I can't seem to get any help from the cart company on how to speed this query up. Maybe I need to add more indexes? I am not sure and would love to get some help that would point me in t right direction to solving this problem.
Thanks,
Chris Edwards
Upvotes: 0
Views: 934
Reputation: 1373
I see a lot of issues with this query that could be causing slowness...
First of all, anywhere you are using 'FIND_IN_SET', try using IN instead. By removing the 'OR' in the conditions, indexes can be used:
cscart_categories.usergroup_ids = ''
OR FIND_IN_SET(0, cscart_categories.usergroup_ids)
OR FIND_IN_SET(1, cscart_categories.usergroup_ids)
Becomes:
cscart_categories.usergroup_ids IN ('', '0', '1')
Other than that, make sure that every column that is being used in a join, group by clause, where clause, or ordering is indexed.
Another suggestion would be to remove the 'GROUP_CONCAT' and select that information separately in another query.
Upvotes: 1