PHP of SQL?
Ik ben bezig met een webshop waarbij bestellingen direct vanuit de leverancier(s) verstuurd worden (dropshipping).
Tevens kunnen klanten afzien van de retour mogelijkheid, waarvoor ze een (extra) korting krijgen op de product prijs.
Als een klant ingelogd is krijgt hij/zij op zijn/haar homepage een overzicht van 'actieve' (dwz in behandeling, in verzending of waarvan de retour termijn nog niet is verstreken) bestellingen.
Ik haal dit op met deze query:
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT order_id, supplier_id, o.order_date,
o.shipping_costs, o.transaction_costs,
os.delivery_date, os.shipping_date,
os.order_supll_status supp_status,
os.track_trace,
COUNT(*) p_by_sup,
COUNT(IF(op.no_return=1, 1, NULL)) no_returns,
COUNT(IF(os.order_supll_status = 2 AND os.delivery_date > '1900-01-01', 1, NULL)) delivered,
SUM(op.amount * op.prd_price) order_total
FROM
orders o
JOIN
orders_products op USING (order_id)
JOIN
products p USING (product_id)
JOIN
orders_by_supplier os USING (order_id, supplier_id)
WHERE
o.account_id = 4 AND (os.delivery_date = '1900-01-01' OR os.delivery_date >= CURRENT_DATE - INTERVAL 14 DAY)
GROUP BY order_id, supplier_id, o.order_date,
o.shipping_costs, o.transaction_costs,
os.delivery_date, os.shipping_date, supp_status, os.track_trace
ORDER BY order_id DESC
o.shipping_costs, o.transaction_costs,
os.delivery_date, os.shipping_date,
os.order_supll_status supp_status,
os.track_trace,
COUNT(*) p_by_sup,
COUNT(IF(op.no_return=1, 1, NULL)) no_returns,
COUNT(IF(os.order_supll_status = 2 AND os.delivery_date > '1900-01-01', 1, NULL)) delivered,
SUM(op.amount * op.prd_price) order_total
FROM
orders o
JOIN
orders_products op USING (order_id)
JOIN
products p USING (product_id)
JOIN
orders_by_supplier os USING (order_id, supplier_id)
WHERE
o.account_id = 4 AND (os.delivery_date = '1900-01-01' OR os.delivery_date >= CURRENT_DATE - INTERVAL 14 DAY)
GROUP BY order_id, supplier_id, o.order_date,
o.shipping_costs, o.transaction_costs,
os.delivery_date, os.shipping_date, supp_status, os.track_trace
ORDER BY order_id DESC
Wat is nu het probleem?
Het resultaat van deze kan (zelfs alleen maar) orders bevatten, waar de retour termijn niet van toepassing en die hoeven dan ook niet in het overzicht getoond worden. Dus in principe haal ik teveel gegevens op, en dat is normaal gesproken niet mijn gewoonte.
Alleen als ik die orders in de sql weg ga filteren krijg bijna dezelfde query als eerste subquery en moet ik daarna bovenstaande query als subquery gaan joinen, betekent dat ie er minimaal 2x zo lang over doet.
Wat zou jullie keuze zijn: weg filteren in php of in sql?
Gewijzigd op 22/10/2013 16:42:54 door Ger van Steenderen
Maar principes zijn er om vanaf geweken te worden (of zoiets). Als het oplossen in sql dusdanig meer tijd kost, terwijl het in php een simpel if statement is, dan zou ik uiteindelijk toch ook wel kiezen voor php. Zelf heb ik ook wel voorbeelden waarbij ik iets in twee queries opknip (met wat php geneuzel ertussen), simpelweg omdat het veel sneller is dan de beste oplossing die ik in sql kan vinden.
Erwin H op 22/10/2013 16:51:19:
Het principiele antwoord is in sql, omdat als het in sql kan, het onzin is om het in php te gaan doen.
Mee eens, om een andere principiële reden: als je alle PHP-script weggooit, moet je de complete orderverwerking kunnen reproduceren met de database. Of omgekeerd beargumenteerd: voor de orderverwerking moet je iets anders (beters?) dan PHP kunnen aansluiten op dezelfde database.
Deze query is op zichzelf al niet snel (0.20 sec gem, met de juiste indexen), het is een mysql database dus where not exists is uitgesloten, dus krijg je 2 subqueries met group by en dat is ook al niet lekker.
Daarnaast kunnen gedeeltes van bestellingen verschillende statussen hebben, dus ik moet het toch al gesplitst binnen krijgen en gaan groeperen in PHP.
En het is inderdaad een simpele if, ik heb het nu voorlopig even in PHP gedaan, straks even kijken wat het sql alternatief me aan performance kost.
Gewijzigd op 22/10/2013 17:58:45 door Ger van Steenderen