Search code examples
sqlmysqloptimizationsql-optimization

SQL Optimization


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 )
)

Solution

  • 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.