How to optimize this?
SELECT e.attr_id, e.sku, a.value
FROM product_attr AS e, product_attr_text AS a
WHERE e.attr_id = a.attr_id
AND value
IN (
SELECT value
FROM product_attr_text
WHERE attribute_id = (
SELECT attribute_id
FROM eav_attr
WHERE attribute_code = 'similar_prod_id'
)
AND value != ''
GROUP BY value
HAVING (COUNT( value ) > 1 )
)
Change it into a JOIN. MySQL doesn't optimize well subqueries in an IN() clause - it is recalculated per row (very inefficient for many rows)
SELECT e.attr_id, e.sku, a.value
FROM product_attr AS e
INNER JOIN product_attr_text AS a ON e.attr_id = a.attr_id
INNER JOIN (SELECT value
FROM product_attr_text
INNER JOIN eav_attr ON eav_attr.attribute_id=product_attr_text.attribute_id
WHERE attribute_code = 'similar_prod_id'
AND value != ''
GROUP BY value
HAVING COUNT( value ) > 1
) AS filter ON filter.value=a.value
After you've converted the query (you may need to make some corrections according to your schema), run EXPLAIN
on the query and index accordingly.