I am doing JOIN from multiple tables to do a facet search. When you avoid JOINs and split the query into two different ones, I noticed a big performance boost, so I assume my JOIN is not optimized.
Structure:
-- tags userId | tagId 1 3 1 4 2 3 2 9 -- search userId | number | countryId | stateId ... 1 13 221 55 -- countries countryId | countryName 221 Somewhere -- users userId | profileImageLink 1 | <photo link>
I am trying to extract all users that have a tag, order according to the search.number number, and transfer metadata from other tables. Request:
SELECT search.*, users.a, users.b, users.c, users.d, users.e, users.f, countries.location_country, states.location_state, cities.location_city FROM search RIGHT JOIN tags ON search.user_id = tags.user_id LEFT JOIN users ON users.user_id=search.user_id LEFT JOIN countries ON countries.countryId=search.countryId LEFT JOIN states ON states.countryId=search.countryId AND states.stateId=search.stateId LEFT JOIN cities ON cities.countryId=search.countryId AND cities.stateId=search.stateId AND cities.cityId=search.cityId WHERE tags.skillId =52772 ORDER BY search.number DESC LIMIT 0,200
I noticed that removing the JOIN in the users table (and after that) makes the query much faster. How can I optimize it to work in a single request? I tried changing FROM to tags instead of searching, but that didn't work ...
Here is what EXPLAIN shows:
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tags ref skill_user,skillId skill_user 4 const 184854 Using index; Using temporary; Using filesort 1 SIMPLE search eq_ref user_id user_id 4 tags.user_id 1 1 SIMPLE countries eq_ref PRIMARY PRIMARY 2 search.countryId 1 1 SIMPLE states eq_ref PRIMARY,state PRIMARY 3 search.stateId 1 1 SIMPLE cities eq_ref PRIMARY,city PRIMARY 3 search.cityId 1 1 SIMPLE users eq_ref user_id user_id 4 search.user_id 1 EXPLAIN without the LEFT JOIN users: id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tags ref skill_user,skillId skill_user 4 const 155870 Using index 1 SIMPLE search eq_ref user_id user_id 4 tags.user_id 1 1 SIMPLE countries eq_ref PRIMARY PRIMARY 2 search.countryId 1 1 SIMPLE states eq_ref PRIMARY,state PRIMARY 3 search.stateId 1 1 SIMPLE cities eq_ref PRIMARY,city PRIMARY 3 search.cityId 1
DESCRIPTION of the request proposed in response:
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tags index NULL userid_skill 8 NULL 22689539 Using where; Using index; Using temporary; Using filesort 1 SIMPLE search eq_ref user_id user_id 4 tags.user_id 1 1 SIMPLE users eq_ref user_id user_id 4 search.user_id 1 1 SIMPLE countries eq_ref PRIMARY PRIMARY 2 search.countryId 1 1 SIMPLE states eq_ref PRIMARY,state PRIMARY 3 search.stateId 1 1 SIMPLE cities eq_ref PRIMARY,city PRIMARY 3 search.cityId 1