Ongelooflijk trage queries met ZF
Voor een website heb ik een aantal vrij grote queries moeten schrijven om de zoekmachine genoeg opties te geven.
Nu maak ik gebruik van drie inner joins om te zoeken op specifieke tabellen (properties tabellen).
In het begin was deze vrij snel omdat er maar 1 inner join was, maar omdat er twee extra velden bij moesten komen is dit nu ongelooflijk traag geworden! Het zoeken duurt nu zo'n 10-15 seconden.
Dit heb ik tijdelijk opgelost door het cachen van de resultaat, maar als de cache moet worden vernieuwd duurt het weer een eeuwigheid.
Ik heb al wat indexes aangemaakt voornamelijk waar de joins op komen, maar heeft niet veel uitgemaakt. Waar kan het aan liggen?
Groeten,
Chris
Daarnaast, cache tabellen opbouwen kan ook met een cronjob
Dan kunnen we meekijken
http://www.slideshare.net/phpcodemonkey/mysql-explain-explained
Verder, aangezien het een search engine betreft, heb je erg veel LIKE statements in je query staan? Die zijn over het algemeen erg traag en als het even kan zou ik daar de aandacht op vestigen. Wellicht dat je die anders kan opstellen, of misschien zelfs wel je hele query opbouw anders. Het scheelt namelijk nogal of je zo'n LIKE doet op de hele tabel of alleen op een subset. Kan je dus je tabel verkleinen (binnen de query) dan kan dat snel al veel tijdswinst opleveren.
Om jullie niet geheel blind te laten staren, heb ik een voorbeeld neergezet om in het algemeen te laten zien hoe het in elkaar zit.
tabel1: - id (primary/index), is_online
tabel1_props: - id(primary), tabel1_id (index), property_name (index), property_value
In princiepe zijn er geen likes in de query. Het is de bedoeling om meerdere properties op te halen die zijn gekoppeld aan tabel1. Maar, omdat er 3 properties in totaal moeten worden opgehaald, die los van elkaar staan, maar met dezelfde tabel1_id, heb ik drie keer in INNER JOIN gedaan. Had ergens gelezen dat een INNER sneller was dan een LEFT( als dat uberhaupt al klopt?)
De query is de volgende (een kleinere query, omdat er nu toevallig wordt gezocht op slechts 1 property. Deze query however, neemt meer dan 30 seconden in beslag(?!):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SELECT tabel1.id
FROM tabel1
INNER JOIN
tabel1_props
ON
tabel1.id = tabel1_props.tabel1_id
INNER JOIN
tabel1_props AS tabel1
ON
tabel1.id = tabel1_props2.tabel1_id
INNER JOIN
tabel1_props AS tabel1_props3
ON
tabel1.id = tabel1_props3.tabel1_id
WHERE tabel1.is_online = 1
AND (
tabel1_props.prop_name = 'specifieke_property'
AND
tabel1_props.prop_value
BETWEEN :pricestart
AND :priceend
)
FROM tabel1
INNER JOIN
tabel1_props
ON
tabel1.id = tabel1_props.tabel1_id
INNER JOIN
tabel1_props AS tabel1
ON
tabel1.id = tabel1_props2.tabel1_id
INNER JOIN
tabel1_props AS tabel1_props3
ON
tabel1.id = tabel1_props3.tabel1_id
WHERE tabel1.is_online = 1
AND (
tabel1_props.prop_name = 'specifieke_property'
AND
tabel1_props.prop_value
BETWEEN :pricestart
AND :priceend
)
Zoals je ziet prepared statements.
De fout is tijdens het schrijven van de reactie al opgelost. Ik wilde een explain doen, deed een verkeerde copy/paste en hij draaide de volledige query. 14.000 records met tabel1.id kwam omhoog. Oftewel, de oplossing is vrij simpel; GROUP BY :)
Doordat de query zoals deze werd opgebouwd in de code zelf bestond uit een kleine 250 regels, hier volledig overheen gekeken.. thanks jongens!
Dat als je op tabel1_props.prop_name een index zet en je between omzet in 2 vergelijkingen de query nog sneller is. Dat kun je met een explain ook bekijken
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT tabel1.id
FROM tabel1
INNER JOIN
tabel1_props
ON
tabel1.id = tabel1_props.tabel1_id
INNER JOIN
tabel1_props AS tabel1
ON
tabel1.id = tabel1_props2.tabel1_id
INNER JOIN
tabel1_props AS tabel1_props3
ON
tabel1.id = tabel1_props3.tabel1_id
WHERE tabel1.is_online = 1
AND (
tabel1_props.prop_name = 'specifieke_property' AND
tabel1_props.prop_value >= :pricestart AND
tabel1_props.prop_value <= :priceend
)
FROM tabel1
INNER JOIN
tabel1_props
ON
tabel1.id = tabel1_props.tabel1_id
INNER JOIN
tabel1_props AS tabel1
ON
tabel1.id = tabel1_props2.tabel1_id
INNER JOIN
tabel1_props AS tabel1_props3
ON
tabel1.id = tabel1_props3.tabel1_id
WHERE tabel1.is_online = 1
AND (
tabel1_props.prop_name = 'specifieke_property' AND
tabel1_props.prop_value >= :pricestart AND
tabel1_props.prop_value <= :priceend
)
Chris op 24/07/2012 16:50:12:
Zoals je ziet prepared statements.
De fout is tijdens het schrijven van de reactie al opgelost. Ik wilde een explain doen, deed een verkeerde copy/paste en hij draaide de volledige query. 14.000 records met tabel1.id kwam omhoog. Oftewel, de oplossing is vrij simpel; GROUP BY :)
Doordat de query zoals deze werd opgebouwd in de code zelf bestond uit een kleine 250 regels, hier volledig overheen gekeken.. thanks jongens!
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SELECT tabel1.id
FROM tabel1
INNER JOIN
tabel1_props
ON
tabel1.id = tabel1_props.tabel1_id
INNER JOIN
tabel1_props AS tabel1
ON
tabel1.id = tabel1_props2.tabel1_id
INNER JOIN
tabel1_props AS tabel1_props3
ON
tabel1.id = tabel1_props3.tabel1_id
WHERE tabel1.is_online = 1
AND (
tabel1_props.prop_name = 'specifieke_property'
AND
tabel1_props.prop_value
BETWEEN :pricestart
AND :priceend
)
FROM tabel1
INNER JOIN
tabel1_props
ON
tabel1.id = tabel1_props.tabel1_id
INNER JOIN
tabel1_props AS tabel1
ON
tabel1.id = tabel1_props2.tabel1_id
INNER JOIN
tabel1_props AS tabel1_props3
ON
tabel1.id = tabel1_props3.tabel1_id
WHERE tabel1.is_online = 1
AND (
tabel1_props.prop_name = 'specifieke_property'
AND
tabel1_props.prop_value
BETWEEN :pricestart
AND :priceend
)
Zoals je ziet prepared statements.
De fout is tijdens het schrijven van de reactie al opgelost. Ik wilde een explain doen, deed een verkeerde copy/paste en hij draaide de volledige query. 14.000 records met tabel1.id kwam omhoog. Oftewel, de oplossing is vrij simpel; GROUP BY :)
Doordat de query zoals deze werd opgebouwd in de code zelf bestond uit een kleine 250 regels, hier volledig overheen gekeken.. thanks jongens!
GROUP BY is geen oplossing, je query is zo traag omdat je 3x hetzelfde doet, nl telkens joinen van dezelfde tabellen op dezelfde kolommen.
Offtopic:
Een prepared statement op een 1 select query levert geen enkele snelheids winst op, sterker nog het kost je snelheid
In deze query wordt er slechts 1 keer gezocht, maar het kan meerdere keren voorkomen. Doe ik die extra in de join, voert hij de query blijkbaar niet uit.. De GROUP by is inderdaad iets trager, maar een stuk sneller in de rest van de programmering. Lastig om uit te leggen, maar voor ieder ID voert hij een stukje uit. Die wordt overigens ook gecached, maar doordat hij het eerst 14.000 keer ipv 30 keer uitvoerde werd dat iets te traag..
Hoe denk jij dat het sneller kan? In de toekomst kan het wel voorkomen dat er 14.000 resultaten zijn. Hoe kan ik dat dan oplossen?
Dat moet niet hoeven. 1 zoekactie moet in 1 query kunnen.
Het ophalen van de gegevens van zo'n ID wordt gecached omdat die op meerdere plekken wordt opgehaald.
Of heb jij een idee hoe je door middel van 1 query, een koppeling kan maken met 4 andere tabellen, en al die gegevens als array terug kan krijgen? Gaat hier om zo'n 30 properties per huis, en nog eens 2-20 properties. Die moete allemaal als array terugkomen. Is dat met 1 query uberhaupt te doen??
Toevoeging op 24/07/2012 18:08:36:
Voor de volledigheid, de query om alle ID's op te halen op basis van 3 properties:
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
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
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
SELECT tabel1.id, tabel1.always_open
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
INNER JOIN
tabel1_properties
ON
tabel1.id = tabel1_properties.tabel1_id
INNER JOIN
tabel1_properties AS tabel1_properties2
ON
tabel1.id = tabel1_properties2.tabel1_id
INNER JOIN
tabel1_properties AS tabel1_properties3
ON
tabel1.id = tabel1_properties3.tabel1_id
WHERE (
(
tabel1.is_online = 1
AND
tabel2.calendar_date = :calendardate
)
OR
(
tabel1.is_online = 1
AND
tabel1.always_open = 1
)
)
AND (
tabel1_properties.prop_name = 'kenmerk1'
AND
tabel1_properties.prop_value
BETWEEN :kenmerk1_1
AND :kenmerk1_2
)
AND (
tabel1_properties2.prop_name = 'kenmerk2'
AND
tabel1_properties2.prop_value != :kenmerk2
)
AND (
tabel1_properties3.prop_name = 'kenmerk3'
AND
tabel1_properties3.prop_value != :kenmerk3
)
GROUP BY tabel1.id
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
INNER JOIN
tabel1_properties
ON
tabel1.id = tabel1_properties.tabel1_id
INNER JOIN
tabel1_properties AS tabel1_properties2
ON
tabel1.id = tabel1_properties2.tabel1_id
INNER JOIN
tabel1_properties AS tabel1_properties3
ON
tabel1.id = tabel1_properties3.tabel1_id
WHERE (
(
tabel1.is_online = 1
AND
tabel2.calendar_date = :calendardate
)
OR
(
tabel1.is_online = 1
AND
tabel1.always_open = 1
)
)
AND (
tabel1_properties.prop_name = 'kenmerk1'
AND
tabel1_properties.prop_value
BETWEEN :kenmerk1_1
AND :kenmerk1_2
)
AND (
tabel1_properties2.prop_name = 'kenmerk2'
AND
tabel1_properties2.prop_value != :kenmerk2
)
AND (
tabel1_properties3.prop_name = 'kenmerk3'
AND
tabel1_properties3.prop_value != :kenmerk3
)
GROUP BY tabel1.id
Als ik dit zo zie denk ik: euh... ga eens normaliseren.
Een kolom met 'kenmerk3' is al fout.
Dat had gewoon een extra tabel moeten zijn met daarin een kolom 'eigenschap_id' en 'waarde_id'.
En dan nog een tabel voor de eigenschappen en eentje voor de waarden (als die categoriseerbaar zijn, zo niet: gewoon een VARCHAR of INT (afhankelijk van de waardes.
Toevoeging op 24/07/2012 18:20:18:
Kletter anders even je database (als dat kan) en anders alleen je structuur in http://sqlfiddle.com/
tabel1: id, is_online, always_online
tabel1_properties: id, tabel1_id, prop_name, prop_value
tabel2: id, tabel1_id, calendar_date
oftewel, het is al genormaliseerd. de prop_name is dus niet vast!
Toevoeging op 24/07/2012 18:22:37:
Voor de duidelijkheid, doe ik niet drie keer een INNER JOIN op tabel1_properties, dan kan hij de resultaten niet vinden! Doe ik wel drie keer INNER JOIN, vind hij pas de resultaten.
Gewijzigd op 24/07/2012 18:24:13 door Chris -
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
INNER JOIN
tabel1_properties AS tabel1_properties2
ON
tabel1.id = tabel1_properties2.tabel1_id
INNER JOIN
tabel1_properties AS tabel1_properties3
ON
tabel1.id = tabel1_properties3.tabel1_id
-- knip --
AND (
tabel1_properties2.prop_name = 'kenmerk2'
AND
tabel1_properties2.prop_value != :kenmerk2
)
AND (
tabel1_properties3.prop_name = 'kenmerk3'
AND
tabel1_properties3.prop_value != :kenmerk3
)
tabel1_properties AS tabel1_properties2
ON
tabel1.id = tabel1_properties2.tabel1_id
INNER JOIN
tabel1_properties AS tabel1_properties3
ON
tabel1.id = tabel1_properties3.tabel1_id
-- knip --
AND (
tabel1_properties2.prop_name = 'kenmerk2'
AND
tabel1_properties2.prop_value != :kenmerk2
)
AND (
tabel1_properties3.prop_name = 'kenmerk3'
AND
tabel1_properties3.prop_value != :kenmerk3
)
tabel1_properties2 en tabel1_properties3 is dezelfde tabel. Beide keren join je tabel1_properties maar geeft ze alleen een andere alias. Je joined ze ook op dezelfde kolommen, dus eigenlijk zou het zo moeten zijn dat tabel1_properties2.prop_name gelijk is aan tabel1_properties3.prop_name. Voor elke rij in je query.
Bovenstaande query zou dus alleen resultaten moeten opleveren als 'kenmerk2' = 'kenmerk3'.
Als dat niet zo is dan heb je denk ik ergens anders een fout zitten. Ik kan namelijk geen enkele situatie voorstellen waar niet zou gelden wat ik net heb geschreven.
Ik had juist alles genormaliseerd omdat het makkelijker zou moeten zijn, maar in de tussentijd lijkt het alleen maar moeilijker en moeilijker te worden :S
Duurt wel even, want het is inderdaad niet het makkelijkste :-)
Onwijs bedankt!
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
SELECT tabel1.id, tabel1.always_open [enderest]
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
LEFT JOIN
tabel1_properties AS tp
ON
tabel1.id = tabel1_properties.tabel1_id
WHERE (
(
tabel1.is_online = 1
AND
tabel2.calendar_date = :calendardate
)
OR
(
tabel1.is_online = 1
AND
tabel1.always_open = 1
)
)
AND (
(
tp.prop_name = 'kenmerk1'
AND
tp.prop_value
BETWEEN :kenmerk1_1 AND :kenmerk1_2
)
OR (
tp.prop_name = 'kenmerk2'
AND
tp.prop_value != :kenmerk2
)
OR (
tp.prop_name = 'kenmerk3'
AND
tp.prop_value != :kenmerk3
))
ORDER BY tabel1.id
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
LEFT JOIN
tabel1_properties AS tp
ON
tabel1.id = tabel1_properties.tabel1_id
WHERE (
(
tabel1.is_online = 1
AND
tabel2.calendar_date = :calendardate
)
OR
(
tabel1.is_online = 1
AND
tabel1.always_open = 1
)
)
AND (
(
tp.prop_name = 'kenmerk1'
AND
tp.prop_value
BETWEEN :kenmerk1_1 AND :kenmerk1_2
)
OR (
tp.prop_name = 'kenmerk2'
AND
tp.prop_value != :kenmerk2
)
OR (
tp.prop_name = 'kenmerk3'
AND
tp.prop_value != :kenmerk3
))
ORDER BY tabel1.id
Edit ik kan een haakje vergeten hebben
Toevoeging op 24/07/2012 18:56:27:
PS:
Je kan LEFT en INNER joins niet door elkaar gebruiken zonder subqueries
Gewijzigd op 24/07/2012 18:59:30 door Ger van Steenderen
Ger, nu heb je overal een OR staan, maar het zijn allemaal AND stukjes. Als ik de INNER in een LEFT JOIN verander, krijg ik alsnog géén resultaten. Met drie INNER JOINs wel.
Als ik het (nu wel) goed begrijp heb je die drie joins nodig omdat je elke rij verschillende kenmerken heeft in de properties tabel en je dus alle rijen moet vinden die alle drie de kenmerken hebben. Elke rij die het eerste kenmerk al niet heeft kan je dus meteen weggooien. Als je die voorwaarde al opneemt in de join voorwaarde zou dat moeten gebeuren. Op deze manier dus:
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
SELECT tabel1.id, tabel1.always_open
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
LEFT JOIN
tabel1_properties
ON (
tabel1.id = tabel1_properties.tabel1_id
AND tabel1_properties.prop_name = 'kenmerk1'
AND tabel1_properties.prop_value
BETWEEN :kenmerk1_1
AND :kenmerk1_2
)
LEFT JOIN
tabel1_properties AS tabel1_properties2
ON (
tabel1.id = tabel1_properties2.tabel1_id
AND tabel1_properties2.prop_name = 'kenmerk2'
AND tabel1_properties2.prop_value != :kenmerk2
)
INNER JOIN
tabel1_properties AS tabel1_properties3
ON (
tabel1.id = tabel1_properties3.tabel1_id
AND tabel1_properties3.prop_name = 'kenmerk3'
AND tabel1_properties3.prop_value != :kenmerk3
)
WHERE (
(
tabel1.is_online = 1
AND
tabel2.calendar_date = :calendardate
)
OR
(
tabel1.is_online = 1
AND
tabel1.always_open = 1
)
)
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
LEFT JOIN
tabel1_properties
ON (
tabel1.id = tabel1_properties.tabel1_id
AND tabel1_properties.prop_name = 'kenmerk1'
AND tabel1_properties.prop_value
BETWEEN :kenmerk1_1
AND :kenmerk1_2
)
LEFT JOIN
tabel1_properties AS tabel1_properties2
ON (
tabel1.id = tabel1_properties2.tabel1_id
AND tabel1_properties2.prop_name = 'kenmerk2'
AND tabel1_properties2.prop_value != :kenmerk2
)
INNER JOIN
tabel1_properties AS tabel1_properties3
ON (
tabel1.id = tabel1_properties3.tabel1_id
AND tabel1_properties3.prop_name = 'kenmerk3'
AND tabel1_properties3.prop_value != :kenmerk3
)
WHERE (
(
tabel1.is_online = 1
AND
tabel2.calendar_date = :calendardate
)
OR
(
tabel1.is_online = 1
AND
tabel1.always_open = 1
)
)
Hierbij gebruik je dus het kenmerk van een LEFT JOIN dat die alleen die rijen selecteert die aan beide kanten van de join een rij heeft die voldoet aan de woorwaarden. Na de eerste join verlies je dus al gelijk alle rijen die het kenmerk niet hebben. Je tweede join is dus al sneller, je derder join nog sneller.
Een andere optie zou zijn om met subqueries te werken, maar ik weet niet of dat nu echte zal gaan helpen in de snelheid. Ik heb het niet helemaal uitgeschreven voor je, alleen de eerste join, de rest mag je zelf erbij bedenken:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT tabel1.id, tabel1.always_open
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
LEFT JOIN (
SELECT DISTINCT(tabel1_id)
FROM tabel1_properties
WHERE tabel1_properties.prop_name = 'kenmerk1'
AND tabel1_properties.prop_value
BETWEEN :kenmerk1_1
AND :kenmerk1_2
) AS tabel1_properties
ON tabel1.id = tabel1_properties.tabel1_id
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
LEFT JOIN (
SELECT DISTINCT(tabel1_id)
FROM tabel1_properties
WHERE tabel1_properties.prop_name = 'kenmerk1'
AND tabel1_properties.prop_value
BETWEEN :kenmerk1_1
AND :kenmerk1_2
) AS tabel1_properties
ON tabel1.id = tabel1_properties.tabel1_id
Ik heb het wat geoptimaliseerd:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SELECT
tabel1.id, tabel1.always_open --[enderest]
FROM
tabel1
LEFT JOIN
tabel2 ON tabel1.id = tabel2.tabel1_id
LEFT JOIN
tabel1_properties AS tp ON tabel1.id = tabel1_properties.tabel1_id
WHERE (
(tabel1.is_online = 1 AND tabel2.calendar_date = :calendardate)
OR
( tabel1.is_online = 1 AND tabel1.always_open = 1)
)
AND (
(tp.prop_name = 'kenmerk1' AND tp.prop_value BETWEEN :kenmerk1_1 AND :kenmerk1_2)
OR
(tp.prop_name = 'kenmerk2' AND tp.prop_value != :kenmerk2)
OR
(tp.prop_name = 'kenmerk3' AND tp.prop_value != :kenmerk3)
)
ORDER BY tabel1.id
tabel1.id, tabel1.always_open --[enderest]
FROM
tabel1
LEFT JOIN
tabel2 ON tabel1.id = tabel2.tabel1_id
LEFT JOIN
tabel1_properties AS tp ON tabel1.id = tabel1_properties.tabel1_id
WHERE (
(tabel1.is_online = 1 AND tabel2.calendar_date = :calendardate)
OR
( tabel1.is_online = 1 AND tabel1.always_open = 1)
)
AND (
(tp.prop_name = 'kenmerk1' AND tp.prop_value BETWEEN :kenmerk1_1 AND :kenmerk1_2)
OR
(tp.prop_name = 'kenmerk2' AND tp.prop_value != :kenmerk2)
OR
(tp.prop_name = 'kenmerk3' AND tp.prop_value != :kenmerk3)
)
ORDER BY tabel1.id
Erwin H op 24/07/2012 19:01:58:
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
SELECT tabel1.id, tabel1.always_open
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
LEFT JOIN
tabel1_properties
ON (
tabel1.id = tabel1_properties.tabel1_id
AND tabel1_properties.prop_name = 'kenmerk1'
AND tabel1_properties.prop_value
BETWEEN :kenmerk1_1
AND :kenmerk1_2
)
LEFT JOIN
tabel1_properties AS tabel1_properties2
ON (
tabel1.id = tabel1_properties2.tabel1_id
AND tabel1_properties2.prop_name = 'kenmerk2'
AND tabel1_properties2.prop_value != :kenmerk2
)
INNER JOIN
tabel1_properties AS tabel1_properties3
ON (
tabel1.id = tabel1_properties3.tabel1_id
AND tabel1_properties3.prop_name = 'kenmerk3'
AND tabel1_properties3.prop_value != :kenmerk3
)
WHERE (
(
tabel1.is_online = 1
AND
tabel2.calendar_date = :calendardate
)
OR
(
tabel1.is_online = 1
AND
tabel1.always_open = 1
)
)
FROM tabel1
LEFT JOIN
tabel2
ON
tabel1.id = tabel2.tabel1_id
LEFT JOIN
tabel1_properties
ON (
tabel1.id = tabel1_properties.tabel1_id
AND tabel1_properties.prop_name = 'kenmerk1'
AND tabel1_properties.prop_value
BETWEEN :kenmerk1_1
AND :kenmerk1_2
)
LEFT JOIN
tabel1_properties AS tabel1_properties2
ON (
tabel1.id = tabel1_properties2.tabel1_id
AND tabel1_properties2.prop_name = 'kenmerk2'
AND tabel1_properties2.prop_value != :kenmerk2
)
INNER JOIN
tabel1_properties AS tabel1_properties3
ON (
tabel1.id = tabel1_properties3.tabel1_id
AND tabel1_properties3.prop_name = 'kenmerk3'
AND tabel1_properties3.prop_value != :kenmerk3
)
WHERE (
(
tabel1.is_online = 1
AND
tabel2.calendar_date = :calendardate
)
OR
(
tabel1.is_online = 1
AND
tabel1.always_open = 1
)
)
YES! Dit is volgens mij de query die ik zoek! Ik herken 'm wel (heb hier eerder mee gewerkt net als jij maar kon niets terug vinden) en dit moet 'm wel zijn. Gelijk even checken!
Edit:
Toon Records 0 - 14 ( 15 totaal, Query duurde 0.0061 sec) :-) Onwijs, heerlijk dit! Eindelijk een snelle query! Ongelooflijk bedankt voor al jullie hulp, Erwin, jij helemaal!
Gewijzigd op 24/07/2012 19:57:29 door Chris -