Eey mensen,

Heb even jullie hulp nodig bij het volgende:

Ten eerste, onderstaande situatie is fictie wat de data betreft. Heb even een "auto" als onderwerp genomen om het makkelijker te begrijpen.

Mijn tabellen:

CAR (ID, NAME)
CATEGORY (ID, PARENT_ID, NAME)
CAR_IN_CATEGORY (ID, CAR_ID, CATEGORY_ID)

Situatie:

Een auto kan aan 1 of meerdere categorieën gekoppeld zijn op welke niveau dan ook.
Het systeem gaat middels een stappen proces door de categorieën. Bij elke stap (categorie boom) moet ik controleren welke categorieen ik nog moet laten zien. Alleen degene welke daaronder nog een auto gekoppeld hebben. Bijv.

2 snelle[=categorie], rode[=categorie], luxe[=categorie] auto's
0 snelle[=categorie], gele[=categorie], luxe[=categorie] auto's

De gele auto hoef ik dus niet te laten zien. Nu heb ik de volgende query om per categorie weergave te controleren of er auto's onder hangen. Ik moet dus alle auto's hebben die gekoppeld zijn aan meerdere geselecteerde categorieën. Een AND verhaal dus, niet een OR.

Huidige QUERY:

SELECT car.id
FROM car_in_category cc
JOIN car c ON car.id = cc.car_id
WHERE cc.category_id IN (119456,119458,119460,119462,119464,119738)
GROUP BY car.id
HAVING COUNT(*) = 6;

119456,119458,119460,119462,119464,119738 <= dit zijn dus de geselecteerde categorieën.

Probleem:

Ik heb op dit moment 60.000 auto's in mijn database welke allen gelinkt zijn aan 1 of meerdere categorieën. Als ik bovenstaande query uitvoer ben ik binnen deze situatie 0.5 tot 1.4 sec bezig. Als ik dat voor 10 categorieën wil doen op een pagina is dat uiteraard niet acceptabel.

Iemand een idee waaraan dit kan liggen of hoe het beter zou kunnen?

Ik heb indexes op alle waardes staan welke gebruikt worden.
Dat is dan ook geen rocket-science. Dus daar ligt het dan toch ook niet aan?

car.id PK
category.id PK
car_in_category.car_id FK
car_in_category.category_id FK

Anyone?

Thanks!
Zodra je kan beperken op de grote tabel krijg je minder output en dus minder i/o waardoor de query sneller resultaat geeft. Moet je dit steeds processen neem dan Oracle ipv MySQL en run je query op 8 cpu cores tegelijk. Succes verzekerd.
Ok, heb je ook een suggestie om de query zo te wijzigen dat ik minder rows tegen kom?
Bijvoorbeeld WHERE merk=BMW and bouwjaar=2010 and model=320
Ik neem aan dar je merk, bouwjaar en model niet in categorie stopt omdat dat dan juist te maken heeft met te ver uitnormaliseren en je performance niet te goede komt. In de 3e normaalvorm horen merk, bouwjaar en model tot de entiteit CAR omdat ze maar 1x voor kunnen komen bij CAR.
Er zijn zoveel verschillende mogelijkheden. Zie de category meer als specificatie. Dan is dit niet te doen om apart op te slaan en jouw situatie na te bootsen. De specs/categorieen zijn in mijn systeem van te voren niet bekend en zijn er meer dan 400...
neem dan Oracle ipv MySQL en run je query op 8 cpu cores tegelijk. Succes verzekerd.
Ja.. dat is natuurlijk niet zo simpel he..

Reageren