So I’ve posted about this query join a few times in the past and we’ve tweaked it a lot, but it still just isn’t as fast as I need it to be. This join is used almost every time we select products on our ecommerce site, so it is important that it is fast.
What this join does is simply select the designer of the product. I’ve done some tweaks to try to improve it and I can shave a good amount of time off, but it really screws up some application logic elsewhere.
Here’s the query as it stands (in an overly simple version):
SELECT *
FROM s01_Products products
LEFT OUTER
JOIN s01_MUS_DesignerLookup mus_designerlookup
ON mus_designerlookup.id = products.designer_id
OR (
products.designer_id IS NULL
AND mus_designerlookup.code = LEFT(products.code, 2)
)
AND mus_designerlookup.active = 1
WHERE products.active = 1
The way product codes (or SKUs) are set up is the first two characters signal which designer the product belongs to (AB-WIDGET would belong to ABC Company, where VA-WIDGET belongs to Vandelay Industries). This can be overridden for some products that don’t fit this form by manually assigning the product to a designer (stored in s01_Products.designer_id). Because of this (we have about 40 / 3000 using this) I have to use a conditional join.
I can tweak the query join to remove the conditional join and the query is 50% faster! The problem, is it changes application logic and our current workflow. Since the LEFT match won’t work on its own, the only option we have for tweaking is manually defining the relationship for every product in our store – which sucks!
So before I figure out how to go that route, can anyone help me with this query? Here’s the EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE products ref active+code active+code 2 const 1048 Using where
1 SIMPLE mus_designerlookup ALL PRIMARY,code NULL NULL NULL 41
I have an index on products.designer_id but it doesn’t seem to help any since 99% of the fields are NULL