Hoe los je het zoeken van meerdere unieke combinaties op, waarbij ook '%' mogen? (En het moet ook no
Nu dacht ik dat ik er was met mijn performance probleem maar nu loop ik toch tegen iets aan. Het is bestaande code waarvan ik de performance wil/moet verbeteren.
Er werd 3 voudige Foreach geneste loop gedaan waarbij iedere keer een bepaalde query werd uitgevoerd:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
<?php
Foreach($this->Jur as Jur) { //5X
Foreach($this->BX as BX) { //6X
Foreach($this->Scene as SceneName) { // 49X
// voor ieder scene wordt er uit drie tabellen data gehaald.
// Deze worden dan in een array geschreven die dan weer bij de aggregatie/totalen gebruikt worden. Het aantal records loopt uiteen van enkele honderden tot 30.000 bv per jur/bx/scene
// Aggregatie van de gegevens van de 3 queries - Dit is niet de bottleneck
// Totalen bepaald - Dit is niet de bottleneck
}
}
}
?>
Foreach($this->Jur as Jur) { //5X
Foreach($this->BX as BX) { //6X
Foreach($this->Scene as SceneName) { // 49X
// voor ieder scene wordt er uit drie tabellen data gehaald.
// Deze worden dan in een array geschreven die dan weer bij de aggregatie/totalen gebruikt worden. Het aantal records loopt uiteen van enkele honderden tot 30.000 bv per jur/bx/scene
// Aggregatie van de gegevens van de 3 queries - Dit is niet de bottleneck
// Totalen bepaald - Dit is niet de bottleneck
}
}
}
?>
$this->Jur is een array met de volgende waarden: '%', 'Jur1', 'Jur2', 'Jur3', 'Jur4'
$this->BU is een array met de volgende waarden: '%', 'BU1', 'BU2', 'BU3', 'BU4', 'BU5'
$this->Scene is een array met de volgende waarden: 'SCENE1', ......, 'SCENE49'
De query die werd uitgevoerd is deze:
Nu dacht ik dit kan ik simpel oplossen. Ik neem het '%' teken niet mee en door de like's en de '=' te vervangen door 'in', dan wordt iedere mogelijke combinatie op gehaald die eerder via de foreach werd opgehaald, althans dat denk ik. Dus dit:
Code (php)
Bij nader inzien realiseer ik mij dat er meer in die Foreach constructie zit!
De '%' waarde die in de array's zijn opgenomen, zijn er voor om de totalen over alles te kunnen bereken en ook nog een keer afzonderlijk per Jur resp. BU entiteiten te berekenen
Mijn vraag is:
Kan ik een query maken waarbij alle mogelijke combinatie met de wildcard '%' voor resp. JUR en BU opgehaald worden, bv. met een OR (al is dat een kostbare performance actie), waarbij ik dan de volgende combi's nog een keer kan ophalen:
JUR - BU - Scene
% - % - (Scene1,... Scene49) //Alle Scene ongeacht JUR/BU
% - BU1 - (Scene1,... Scene49) //Voor BU1 + alle Scene ongeacht JUR
% - BU2 - (Scene1,... Scene49) //Voor BU2 + alle Scene ongeacht JUR
| etc. // etc t/m Jur4
Jur1 - % - (Scene1,... Scene49) // idem maar dan voor de BU
Jur2 - % - (Scene1,... Scene49)
Dit lukt niet meer met een 'in' vanwege '%'. Om alles specifiek uit te programmeren lijkt mij niet de oplossing. Maar hoe kun je dit oplossen? Of moet je UNION gaan maken?
Ik hoop dat ik het een beetje duidelijk heb kunnen maken of dat anders mensen aanvoelen wat ik bedoel of het probleem is.
****EDIT****
Nu ik dit zo opgeschreven heb en proberen uit te leggen krijg ik het gevoel dat dit (enkel) met een Union opgelost kan worden temeer omdat ik dan ook voor Jur resp. BU zelf een naam kan geven. Ik weet alleen niet wat dit met de performance doet.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
SELECT
....
AND Jur in (Jur waarden array)//dit zijn alle elementen van het array met uitzondering van '%'
AND BU in (BU waarden array) //dit zijn alle elementen van het array met uitzondering van '%'
AND Scene in (Scene waarden array)
UNION
Select 'Jur_naam' as JUR //Deze UNION is vervanger als JUR = % en BU = %
,'Bu_naam' as BU
....
AND Scene in (Scene waarden array)
UNION
Select 'Jur_naam' as JUR //Is vervanger als JUR = % maar per BU
,BU
....
AND BU in (BU waarden array) //dit zijn alle elementen van het array met uitzondering van '%'
AND Scene in (Scene waarden array)
UNION
Select Jur //Is vervanger als BU = % maar per JUR
,'Bu_naam' as BU
....
AND Jur in (Jur waarden array)//dit zijn alle elementen van het array met uitzondering van '%'
AND Scene in (Scene waarden array)
?>
SELECT
....
AND Jur in (Jur waarden array)//dit zijn alle elementen van het array met uitzondering van '%'
AND BU in (BU waarden array) //dit zijn alle elementen van het array met uitzondering van '%'
AND Scene in (Scene waarden array)
UNION
Select 'Jur_naam' as JUR //Deze UNION is vervanger als JUR = % en BU = %
,'Bu_naam' as BU
....
AND Scene in (Scene waarden array)
UNION
Select 'Jur_naam' as JUR //Is vervanger als JUR = % maar per BU
,BU
....
AND BU in (BU waarden array) //dit zijn alle elementen van het array met uitzondering van '%'
AND Scene in (Scene waarden array)
UNION
Select Jur //Is vervanger als BU = % maar per JUR
,'Bu_naam' as BU
....
AND Jur in (Jur waarden array)//dit zijn alle elementen van het array met uitzondering van '%'
AND Scene in (Scene waarden array)
?>
Volgens mij moet ik het op deze manier oplossen, in combinatie met mijn eerdere query. Of is er een expert die een betere oplossing weet of heeft?
Bedankt,
Nico.
Gewijzigd op 27/07/2017 16:51:22 door Nkamp Kamp van de
en je maakt een extra tabel: jurren.
Daarin zet je de genoemde strings en een (auto increment) id.
id name
1 Jur1
2 Jur2
3 Foo
4 Jur3
(en ik kies bewust niet een oplopende lijst :-p
De INT die je nu in je tabel hebt staan, verbind je als Foreign Key naar de Jurren-tabel.
Je kunt nu (waarschijnlijk snel) zoeken naar
WHERE jur_id = 4
Idem voor de BU en Scenes, mits ook daar de strings van te voren vast liggen.
Gewijzigd op 27/07/2017 17:28:54 door Ben van Velzen
@ivo ik begrijp niet helemaal wat je bedoeld.
@Ben, het is allemaal op dezelfde tabel! Waar het omgaat is dat met die foreach constructie iedere combinatie discreet werd afgehandeld, maar daardoor ging de performance helemaal stuk. Nu wil ik alles in 1x ophalen alle mogelijke combinaties die ook in de foreach discreet werden gedaan, Dus ook met de wilcards.
Nu met de wildcards haal ik eigenlijk alles nog een keer op + nog een aantal extra waarvan de jur resp. BU leeg is.
Dit is blijkbaar wel voor het berekenen van de totalen.
Nu kan ik bij de UNION ALL zelf een waarde invullen als het om de wildcards gaat dus iets als: SELECT 'Jur_Naam' as JUR.
Het voordeel hiervan is dan, althans zoals ik het in mijn gedachten heb, in de while weer zelf kan onderscheiden dat die records voor de totalen gebruikt moeten worden.
Het is zoals het is voor dit moment even.
-- VRAAG:
UNION haalt de duplicaten er uit. Een UNION ALL daarentegen niet.
Nu heb ik de twee qeuries via een UNION ALL gekoppeld.
Als ik deze queries afzonderlijk draai geeft de ene een resultaat terug van 1197 en de ander van 1204.
Bij een UNION ALL zou ik dan resultaatset van 2401 verwachten, maar ik zie in MySQL Workbench 1205 staan, een meer als de laatste, daar begrijp ik niets van.
Klopt mijn verwachting niet of komt dit doordat je een UNION ALL op dezelfde tabel doet of...?