[英]MySQL how to optimize query with bunch of subqueries
I have one huge project where I need to made statistics. 我有一个庞大的项目需要统计。 This query give me accurate results but is a bit slow on loading and need somehow to optimize it but can't figure out how. 该查询为我提供了准确的结果,但加载速度有点慢,需要某种方式对其进行优化 ,但无法弄清楚该怎么做。
SELECT
TRIM(`op`.`products_quantity`) AS `products_quantity`,
TRIM(`op`.`products_price`) AS `products_price`,
TRIM(`op`.`orders_products_status`) AS `orders_products_status`,
TRIM(`p`.`product_type`) AS `product_type`,
IF(`p`.`product_type` IN ('G'),FLOOR(`op`.`final_price`*`op`.`products_quantity`),
`op`.`final_price`) AS `final_price`,
TRIM((
SELECT
`o`.`payment_method`
FROM
`orders` `o`
WHERE
`o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
)) AS `payment_method`,
IF(
TRIM(DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%d/%m/%Y')) LIKE (
SELECT
TRIM(DATE_FORMAT(`o`.`date_purchased`,'%d/%m/%Y'))
FROM
`orders` `o`
WHERE
`o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
),
1,0
) AS `same_day`
FROM
`categories` `c`,
`categories_description` `cd`,
`products` `p`,
`orders_products` `op`
WHERE
`c`.`section_id` = 25
AND
`cd`.`categories_id` = `c`.`categories_id`
AND
`p`.`section_id` = `c`.`section_id`
AND
`p`.`product_type` IN ('P')
AND
`op`.`products_id` = `p`.`products_id`
GROUP BY `op`.`orders_products_id`
ORDER BY `payment_method` ASC
Do anyone have some suggestion? 有人有建议吗?
I would like also some good explanation from SQL experts how is the best way to organize similar query and what need to be first inside WHERE
section. 我还想从SQL专家那里得到一些很好的解释,如何组织相似查询的最佳方法是什么,首先需要在WHERE
部分中进行什么。
You can do this more better way by Joining all tables by using JION 您可以通过使用JION 连接所有表来实现更好的方法
Try like this :- 尝试这样:-
SELECT
TRIM(`op`.`products_quantity`) AS `products_quantity`,
TRIM(`op`.`products_price`) AS `products_price`,
TRIM(`op`.`orders_products_status`) AS `orders_products_status`,
TRIM(`p`.`product_type`) AS `product_type`,
IF(`p`.`product_type` IN ('G'),FLOOR(`op`.`final_price`*`op`.`products_quantity`),
`op`.`final_price`) AS `final_price`,
TRIM((
SELECT
`o`.`payment_method`
FROM
`orders` `o`
WHERE
`o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
)) AS `payment_method`,
IF(
TRIM(DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%d/%m/%Y')) LIKE (
SELECT
TRIM(DATE_FORMAT(`o`.`date_purchased`,'%d/%m/%Y'))
FROM
`orders` `o`
WHERE
`o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
),
1,0
) AS `same_day`
FROM
`categories` `c`
join `categories_description` `cd` on `cd`.`categories_id` = `c`.`categories_id`
join `products` `p` on `p`.`section_id` = `c`.`section_id`
join `orders_products` `op` on `op`.`products_id` = `p`.`products_id`
WHERE
`c`.`section_id` = 25
AND
`p`.`product_type` IN ('P')
GROUP BY `op`.`orders_products_id`
ORDER BY `payment_method` ASC
You can try and run few basic steps: 您可以尝试运行一些基本步骤:
As there is no data, I am not able to verify the query. 由于没有数据,因此我无法验证查询。 But I think the following optional query may be helpful: 但我认为以下可选查询可能会有所帮助:
SELECT
TRIM(`op`.`products_quantity`) AS `products_quantity`,
TRIM(`op`.`products_price`) AS `products_price`,
TRIM(`op`.`orders_products_status`) AS `orders_products_status`,
TRIM(`p`.`product_type`) AS `product_type`,
IF(`p`.`product_type` = 'G', FLOOR(`op`.`final_price` * `op`.`products_quantity`), `op`.`final_price`) AS `final_price`,
TRIM(`t`.`payment_method`) AS `payment_method`,
IF( TRIM(DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%d/%m/%Y')) LIKE
TRIM(DATE_FORMAT(`t`.`date_purchased`,'%d/%m/%Y')), 1, 0 ) AS `same_day`
FROM
`categories` `c` INNER JOIN `categories_description` `cd` ON `c`.`categories_id` = `cd`.`categories_id`
INNER JOIN `products` `p` ON `c`.`section_id` = `p`.`section_id`
INNER JOIN `orders_products` `op` ON `p`.`products_id` = `op`.`products_id`
INNER JOIN
( SELECT `o`.`orders_id`, `o`.`payment_method`,
TRIM(DATE_FORMAT(`o`.`date_purchased`,'%d/%m/%Y')) AS `date_purchased`
FROM `orders` `o` GROUP BY `o`.`orders_id` ) AS `t` ON `op`.`orders_id` = `t`.`orders_id`
WHERE `c`.`section_id` = 25 AND `p`.`product_type` IN ('P')
GROUP BY `op`.`orders_products_id`
ORDER BY `payment_method`;
Please note that following portion was common for both Inner sub-queries: 请注意,以下两个部分对于两个内部子查询都是相同的:
FROM `orders` `o`
WHERE `o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
Which means you are referring to the same table with same conditions twice, just to get two different columns. 这意味着您要两次引用具有相同条件的同一张表,只是为了获得两个不同的列。 So I have removed that part and added it as INNER JOIN
of single sub-query. 因此,我删除了该部分并将其添加为单个子查询的INNER JOIN
。
Also note that there is only one value in bracket for both IN
. 另请注意,两个IN
括号中只有一个值。 So I have replaced IN
by =
. 所以我用=
代替了IN
。
Please let me know if this is helpful to you. 如果这对您有帮助,请告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.