Beste,
Ik zit met een probleempje qua optimalisatie van een query.
Even korte uitleg
Ik heb de volgende tabellen
s_fil = bestanden
s_fil_rol_rd = bestand schrijf rollen
s_fol = map namen
s_prt_grp_rol = koppeltabel rollen naar groepen
s_prt_grp_prt = koppeltabel groepen naar gebruikers
Een gebruiker kan dus in 1 of meerdere groepen zitten en elke groep kan 1 of meerdere rollen hebben
Verder heeft een bestand ook 1 of meerdere rollen.
Nu wilde ik dus graag met 1 query alle bestanden waar een gebruiker schrijf rollen voor heeft (of waar geen rollen gedefineerd zijn) ophalen.
Uiteindelijk kwam ik uit bij de volgende query.
Nu is echter de explain output alsvolgt.
Hij gebruikt een temp table
Echter als ik hem zonder de join naar s_fol (mappen) doe dus zoeits als
Dan is de explain alsvolgt
Nu gebruikt hij geen temp table
Kan het komen doordat ik in de group by (groepeer op kolommen uit 2 tabellen dat mysql daar dus altijd een temp van moet maken)
of is er een andere manier om dit te voorkomen
Ik heb het net ook geprobeerd via een subquery....maar dit duurt meteen 1.4 sec in MySQL
Ik zit met een probleempje qua optimalisatie van een query.
Even korte uitleg
Ik heb de volgende tabellen
s_fil = bestanden
s_fil_rol_rd = bestand schrijf rollen
s_fol = map namen
s_prt_grp_rol = koppeltabel rollen naar groepen
s_prt_grp_prt = koppeltabel groepen naar gebruikers
Een gebruiker kan dus in 1 of meerdere groepen zitten en elke groep kan 1 of meerdere rollen hebben
Verder heeft een bestand ook 1 of meerdere rollen.
Nu wilde ik dus graag met 1 query alle bestanden waar een gebruiker schrijf rollen voor heeft (of waar geen rollen gedefineerd zijn) ophalen.
Uiteindelijk kwam ik uit bij de volgende query.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| SELECT a.id, a.name, s_fol.name foldername FROM s_fil a INNER JOIN s_fol ON a.s_fol_id = s_fol.id LEFT OUTER JOIN s_fil_rol_rd b ON a.id = b.s_fil_id LEFT OUTER JOIN s_prt_grp_rol d ON b.s_rol_id = d.s_rol_id LEFT OUTER JOIN s_prt_grp_prt e ON d.s_prt_grp_id = e.s_prt_grp_id WHERE (e.s_prt_id = 3 OR e.s_prt_id IS NULL) GROUP BY a.id, a.name, s_fol.name ORDER BY NULL |
Nu is echter de explain output alsvolgt.
Hij gebruikt een temp table
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | s_fol | index | PRIMARY,id | s_fol_name_idx | 768 | 37 | Using index; Using temporary | |
1 | SIMPLE | a | ref | s_fil_s_fol_fk | s_fil_s_fol_fk | 8 | synone.s_fol.id | 5 | |
1 | SIMPLE | b | ref | PRIMARY | PRIMARY | 8 | synone.a.id | 1 | Using index |
1 | SIMPLE | d | ref | s_prt_grp_rol_s_rol_fk | s_prt_grp_rol_s_rol_fk | 8 | synone.b.s_rol_id | 1 | Using index |
1 | SIMPLE | e | ref | s_prt_grp_prt_s_prt_grp_fk | s_prt_grp_prt_s_prt_grp_fk | 8 | synone.d.s_prt_grp_id | 1 | Using where; Using index |
Echter als ik hem zonder de join naar s_fol (mappen) doe dus zoeits als
code:
1
2
3
4
5
6
7
8
9
10
11
12
| SELECT a.id, a.name FROM s_fil a LEFT OUTER JOIN s_fil_rol_rd b ON a.id = b.s_fil_id LEFT OUTER JOIN s_prt_grp_rol d ON b.s_rol_id = d.s_rol_id LEFT OUTER JOIN s_prt_grp_prt e ON d.s_prt_grp_id = e.s_prt_grp_id WHERE (e.s_prt_id = 3 OR e.s_prt_id IS NULL) GROUP BY a.id, a.name |
Dan is de explain alsvolgt
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | a | index | dsad342 | 775 | 273 | Using index | ||
1 | SIMPLE | b | ref | PRIMARY | PRIMARY | 8 | synone.a.id | 1 | Using index |
1 | SIMPLE | d | ref | s_prt_grp_rol_s_rol_fk | s_prt_grp_rol_s_rol_fk | 8 | synone.b.s_rol_id | 1 | Using index |
1 | SIMPLE | e | ref | s_prt_grp_prt_s_prt_grp_fk | s_prt_grp_prt_s_prt_grp_fk | 8 | synone.d.s_prt_grp_id | 1 | Using where; Using index |
Nu gebruikt hij geen temp table
Kan het komen doordat ik in de group by (groepeer op kolommen uit 2 tabellen dat mysql daar dus altijd een temp van moet maken)
of is er een andere manier om dit te voorkomen
Ik heb het net ook geprobeerd via een subquery....maar dit duurt meteen 1.4 sec in MySQL
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| SELECT a.id, a.name, s_fol.name foldername FROM s_fil a INNER JOIN s_fol ON a.s_fol_id = s_fol.id WHERE a.id IN ( SELECT a.id FROM s_fil a LEFT OUTER JOIN s_fil_rol_rd b ON a.id = b.s_fil_id LEFT OUTER JOIN s_prt_grp_rol d ON b.s_rol_id = d.s_rol_id LEFT OUTER JOIN s_prt_grp_prt e ON d.s_prt_grp_id = e.s_prt_grp_id WHERE (e.s_prt_id = 3 OR e.s_prt_id IS NULL) GROUP BY a.id ) |
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | PRIMARY | s_fol | index | PRIMARY,id | s_fol_name_idx | 768 | 37 | Using index | |
1 | PRIMARY | a | ref | s_fil_s_fol_fk | s_fil_s_fol_fk | 8 | synone.s_fol.id | 5 | Using where |
2 | DEPENDENT SUBQUERY | a | index | PRIMARY | 8 | 273 | Using index | ||
2 | DEPENDENT SUBQUERY | b | ref | PRIMARY | PRIMARY | 8 | synone.a.id | 1 | Using index |
2 | DEPENDENT SUBQUERY | d | ref | s_prt_grp_rol_s_rol_fk | s_prt_grp_rol_s_rol_fk | 8 | synone.b.s_rol_id | 1 | Using index |
2 | DEPENDENT SUBQUERY | e | ref | s_prt_grp_prt_s_prt_grp_fk | s_prt_grp_prt_s_prt_grp_fk | 8 | synone.d.s_prt_grp_id | 1 | Using where; Using index |
[ Voor 22% gewijzigd door vorlox op 07-03-2009 14:53 ]