Deze query doet er 3.7773 sec over:
Als ik die twee subqueries apart uitvoer, en de resultaten als verzameling opgeef, doet hij er nog maar 0.0170 sec over:
En de subqueries die vervangen zijn gaan nog sneller dan dat, dus het is gewoon honderd keer zo snel. Nou houd ik er zelf van om alle logica op een zelfde plek te houden, en niet te verspreiden door scripts heen, kortom, het liefste een query per blok data.
Ik denk zelf dat MySQL de mist in gaat doordat het steeds opnieuw die subquery uitvoert in plaats van het als een vaste verzameling te zien (wat het duidelijk gewoon is), is er een manier om er voor te zorgen dat de interpreter het wel zo ziet waardoor ik niet meer met losse queries hoef te werken?
Edit:
EXPLAIN resultaat van de eerste query:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
| SELECT it.id, it.type, max( if( it.id = icr.child_item_id AND parent_item_id =77, 1, 0 ) ) AS `is parent` , max( if( it.id = icr.parent_item_id AND child_item_id =77, 1, 0 ) ) AS `is child` , max( if( it.id = icr.child_item_id AND parent_item_id !=77, 1, 0 ) ) AS `is sibling` FROM item_type it, item_child_restriction icr WHERE ( it.id = icr.child_item_id AND parent_item_id =77 ) OR ( ( child_item_id IN ( SELECT child_item_id FROM item_child_restriction WHERE parent_item_id IN ( SELECT parent_item_id FROM item_child_restriction WHERE parent_item_id =19 ) ) ) AND ( ( it.id = icr.parent_item_id AND child_item_id =77 ) OR ( it.id = icr.child_item_id AND parent_item_id !=77 AND parent_item_id IN ( SELECT parent_item_id FROM item_child_restriction WHERE ( child_item_id =77 ) ) ) ) ) GROUP BY it.type |
Als ik die twee subqueries apart uitvoer, en de resultaten als verzameling opgeef, doet hij er nog maar 0.0170 sec over:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| SELECT it.id, it.type, max( if( it.id = icr.child_item_id AND parent_item_id = 15, 1, 0 ) ) AS `is parent`, max( if( it.id = icr.parent_item_id AND child_item_id = 15, 1, 0 ) ) AS `is child`, max( if( it.id = icr.child_item_id AND parent_item_id != 15, 1, 0 ) ) AS `is sibling` FROM item_type it, item_child_restriction icr WHERE ( it.id = icr.child_item_id AND parent_item_id = 15 ) OR ( ( child_item_id IN (7, 14, 15, 16, 17, 20, 23, 33, 34, 36, 38, 46, 48, 56, 61, 62, 63, 64, 65, 66, 70, 77) ) AND ( ( it.id = icr.parent_item_id AND child_item_id = 15 ) OR ( it.id = icr.child_item_id AND parent_item_id != 15 AND parent_item_id IN ( 1, 7, 15, 17, 19, 20, 21, 22, 23, 51, 52, 56, 58, 70, 71 ) ) ) ) GROUP BY it.type |
En de subqueries die vervangen zijn gaan nog sneller dan dat, dus het is gewoon honderd keer zo snel. Nou houd ik er zelf van om alle logica op een zelfde plek te houden, en niet te verspreiden door scripts heen, kortom, het liefste een query per blok data.
Ik denk zelf dat MySQL de mist in gaat doordat het steeds opnieuw die subquery uitvoert in plaats van het als een vaste verzameling te zien (wat het duidelijk gewoon is), is er een manier om er voor te zorgen dat de interpreter het wel zo ziet waardoor ik niet meer met losse queries hoef te werken?
Edit:
EXPLAIN resultaat van de eerste query:
code:
1
2
3
4
5
| 1 PRIMARY it index PRIMARY type 22 NULL 78 Using index; Using temporary; Using filesort 1 PRIMARY icr index PRIMARY,parent_item_id,child_item_id parent_item_id 4 NULL 1723 Using where; Using index 4 DEPENDENT SUBQUERY item_child_restriction unique_subquery PRIMARY,parent_item_id,child_item_id PRIMARY 8 func,const 1 Using index; Using where 2 DEPENDENT SUBQUERY item_child_restriction index_subquery child_item_id child_item_id 4 func 10 Using index; Using where 3 DEPENDENT SUBQUERY item_child_restriction ref PRIMARY,parent_item_id parent_item_id 4 const 22 Using where; Using index |
[ Voor 12% gewijzigd door BikkelZ op 06-12-2006 12:41 ]
iOS developer