Here is massimo suggested code:
mysql> explain SELECT
groups.name,
city.name,
auth_user.id, auth_user.is_active, auth_user.created_on, auth_user.created_by, auth_user.modified_on, auth_user.modified_by, auth_user.email, auth_user.person_id, auth_user.password, auth_user.know_id, auth_user.registration_key, auth_user.reset_password_key, auth_user.registration_id FROM researcher, researcher_lab_permission, lab, groups, auth_user, city WHERE ((((((((
groups.id = lab.group_id) AND (
lab.id = researcher_lab_permission.lab_id)) AND (
researcher.id = researcher_lab_permission.researcher_id)) AND (researcher.user_id =
auth_user.id)) AND (researcher_lab_permission.is_active = 'T')) AND (lab.is_active = 'T')) AND (groups.is_active = 'T')) AND (auth_user.is_active = 'T'))
-> ;
+----+-------------+---------------------------+--------+--------------------------------+---------+---------+------------------------------------------------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------------+--------+--------------------------------+---------+---------+------------------------------------------------+------+--------------------------------+
| 1 | SIMPLE | city | ALL | NULL | NULL | NULL | NULL | 5535 | |
| 1 | SIMPLE | researcher_lab_permission | ALL | researcher_id__idx,lab_id__idx | NULL | NULL | NULL | 2 | Using where; Using join buffer |
| 1 | SIMPLE | lab | eq_ref | PRIMARY,group_id__idx | PRIMARY | 4 | labsyn.researcher_lab_permission.lab_id | 1 | Using where |
| 1 | SIMPLE | groups | eq_ref | PRIMARY | PRIMARY | 4 | labsyn.lab.group_id | 1 | Using where |
| 1 | SIMPLE | researcher | eq_ref | PRIMARY,user_id__idx | PRIMARY | 4 | labsyn.researcher_lab_permission.researcher_id | 1 | |
| 1 | SIMPLE | auth_user | eq_ref | PRIMARY | PRIMARY | 4 | labsyn.researcher.user_id | 1 | Using where |
+----+-------------+---------------------------+--------+--------------------------------+---------+---------+------------------------------------------------+------+--------------------------------+
Here is with JOIN:
explain SELECT
l.id,
g.name,
c.name FROM researcher_lab_permission as rl JOIN lab as l
-> JOIN researcher as r JOIN auth_user as a JOIN groups as g JOIN city as c
-> ON rl.researcher_id =
r.id AND rl.lab_id =
l.id AND
a.id = r.user_id AND l.group_id =
g.id
-> AND
c.id = g.city_id
-> ;
+----+-------------+-------+--------+--------------------------------+-----------------+---------+-------------------------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------------------+-----------------+---------+-------------------------+------+--------------------------------+
| 1 | SIMPLE | l | index | PRIMARY,group_id__idx | group_id__idx | 5 | NULL | 2 | Using index |
| 1 | SIMPLE | rl | ALL | researcher_id__idx,lab_id__idx | NULL | NULL | NULL | 2 | Using where; Using join buffer |
| 1 | SIMPLE | a | index | PRIMARY | created_by__idx | 5 | NULL | 2 | Using index; Using join buffer |
| 1 | SIMPLE | r | eq_ref | PRIMARY,user_id__idx | PRIMARY | 4 | labsyn.rl.researcher_id | 1 | Using where |
| 1 | SIMPLE | g | eq_ref | PRIMARY,city_id__idx | PRIMARY | 4 | labsyn.l.group_id | 1 | |
| 1 | SIMPLE | c | eq_ref | PRIMARY | PRIMARY | 4 | labsyn.g.city_id | 1 | |
+----+-------------+-------+--------+--------------------------------+-----------------+---------+-------------------------+------+--------------------------------+
Without natural join it's getting all the cities first without any optimizations. So I observed that that code was not filtering cities.