Reputation: 1354
I am generating a CSV of how many orders I have every month for the last 12 months per item. At the moment I am retrieving the items and using a foreach loop to submit the following query for each item, in order to retrieve the total times it has been ordered in each month over the past 12 months. However, the query takes just over 3 seconds, so when the loop goes a couple of thousand times, it causes the MySQL server to go away.
How could I optimise this query? Should the load on the database be reduced if I use a sub query instead?
Here is the query(which was adapted from here):
SELECT order_item_variant_alias_id, DATE(DATE_FORMAT(order_progress_time, '%Y-%m-01')) AS `trueMonth`, COUNT(*) AS count
FROM tbl_order_progress
JOIN tbl_order_items ON order_progress_order_id = order_item_order_id
JOIN tbl_product_variant_aliases ON order_item_variant_alias_id = product_variant_alias_id
JOIN tbl_product_variants ON product_variant_id = product_variant_alias_variant_id
GROUP BY product_variant_alias_id, DATE(DATE_FORMAT(order_progress_time, '%Y-%m-01'))
HAVING order_item_variant_alias_id = 1
Upvotes: 0
Views: 35
Reputation: 1269683
Why are you running a separate query for each item? Just drop the having
clause and put all items in at the same time.
If, for some reason, you do need to do one item at a time, switch the logic to a where
clause rather than a having
clause. The having
clause will aggregate all items and then filter down to the one you want. MySQL should be faster if you reduce the data first -- using where
:
SELECT order_item_variant_alias_id,
DATE(DATE_FORMAT(order_progress_time, '%Y-%m-01')) AS `trueMonth`,
COUNT(*) AS count
FROM tbl_order_progress JOIN
tbl_order_items
ON order_progress_order_id = order_item_order_id JOIN
tbl_product_variant_aliases
ON order_item_variant_alias_id = product_variant_alias_id JOIN
tbl_product_variants
ON product_variant_id = product_variant_alias_variant_id
WHERE order_item_variant_alias_id = 1
GROUP BY product_variant_alias_id,
DATE(DATE_FORMAT(order_progress_time, '%Y-%m-01'));
Upvotes: 1