I am working with a legacy database schema that looks like this:
product_table table has fields:
uid (int, primary key)
name (varchar 50)
category table has fields:
uid (int, primary key)
name (varchar 50)
Allright, now the product_table has 4 MM relations to the category table:
product_table__category_1__mm has fields:
uid_local (int, contains product_table.uid)uid_foreign (int, contains category.uid)
product_table__category_2__mm has fields:
uid_local (int, contains product_table.uid)uid_foreign (int, contains category.uid)
product_table__category_3__mm has fields:
uid_local (int, contains product_table.uid)uid_foreign (int, contains category.uid)
product_table__category_4__mm has fields:
uid_local (int, contains product_table.uid)uid_foreign (int, contains category.uid)
(yes, all the 4 MM tables have the same fields and all relate to the category table)
So, if I want to pull in all four joins and filter based on int values selected by the user it would look something like this:
select
product_table.*
from
product_table
inner join product_table__category_1__mm mm_1 on mm_1.uid_local = product_table.uid
inner join category cat_1 on cat_1.uid = mm_1.uid_foreign and cat_1.uid in (7, 8)
inner join product_table__category_2__mm mm_2 on mm_2.uid_local = product_table.uid
inner join category cat_2 on cat_2.uid = mm_2.uid_foreign and cat_2.uid in (63, 52)
inner join product_table__category_3__mm mm_3 on mm_3.uid_local = product_table.uid
inner join category cat_3 on cat_3.uid = mm_3.uid_foreign and cat_3.uid in (84, 12)
inner join product_table__category_4__mm mm_4 on mm_4.uid_local = product_table.uid
inner join category cat_4 on cat_4.uid = mm_4.uid_foreign and cat_4.uid in (16, 33)
group by product_table.uid ### --> in order to get unique results
Now thats a big query, but I cant change the db design as it is already widely in use.
Any idea on how to make this query faster? Where would you put indexes?
You need to get rid of
GROUP BYhere.MySQLis not good in optimizing it.Rewrite your query as this:
Create the indexes:
or, better, declare them
PRIMARY KEYsonproduct_table__category_*__mm: