I need to optimize mysql select query or make it fasterMySQL query with join optimizationMySQL query optimization JOINMySQL query optimizationHow to optimize a count SQL query on a big tableOptimizing MySQL query with inner joinHow i can optimize my mysql query?Indexes in Mysql Query behaving indifferentlyOptimize mysql query with subqueriesOptimizing this MySQL query with a subquery insideMySQL - Slow Query when kept a View

Could Boris Johnson face criminal charges for illegally proroguing Parliament?

Why the first octet of a MAC address always end with a binary 0?

Using RECURSIVE in Virtual Layer

Why does `FindFit` fail so badly in this simple case?

What are one's options when facing religious discrimination at the airport?

Isn't the detector always measuring, and thus always collapsing the state?

As a team leader is it appropriate to bring in fundraiser candy?

Knights and Knaves: What does C say?

Booting Ubuntu from USB drive on MSI motherboard -- EVERYTHING fails

Did Joe Biden "stop a prosecution" into his son in Ukraine? And did he brag about stopping the prosecution?

Short story about a potato hotel that makes its guests into potatoes throughout the night

"Tenersi pronto" = to get ready or to be ready

Why do Russians sometimes spell "жирный" (fatty) as "жырный"?

What is the point of impeaching Trump?

What's the correct way to determine turn order in this situation?

Where does the image of a data connector as a sharp metal spike originate from?

How dangerous are my worn rims?

Is spot metering just an EV compensation?

What does a textbook look like while you are writing it?

Why has Speaker Pelosi been so hesitant to impeach President Trump?

Are there types of animals that can't make the trip to space? (physiologically)

Does it require less energy to reach the Sun from Pluto's orbit than from Earth's orbit?

Why do personal finance apps focus on outgoings rather than income

If I travelled back in time to invest in X company to make a fortune, roughly what is the probability that it would fail?



I need to optimize mysql select query or make it faster


MySQL query with join optimizationMySQL query optimization JOINMySQL query optimizationHow to optimize a count SQL query on a big tableOptimizing MySQL query with inner joinHow i can optimize my mysql query?Indexes in Mysql Query behaving indifferentlyOptimize mysql query with subqueriesOptimizing this MySQL query with a subquery insideMySQL - Slow Query when kept a View






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









2















I have a select query, that selects over 50k records from mysql 5.5 database at once, and this amount is expected to grow. The query contains multiple subquery which is taking over 120s to execute.



Initially some of the sale_items and stock tables didnt have more that the ID keys, so i added some more



SELECT
`p`.`id` AS `id`,
`p`.`Name` AS `Name`,
`p`.`Created` AS `Created`,
`p`.`Image` AS `Image`,
`s`.`company` AS `supplier`,
`s`.`ID` AS `supplier_id`,
`c`.`name` AS `category`,
IFNULL((SELECT
SUM(`stocks`.`Total_Quantity`)
FROM `stocks`
WHERE (`stocks`.`Product_ID` = `p`.`id`)), 0) AS `total_qty`,
IFNULL((SELECT
SUM(`sale_items`.`quantity`)
FROM `sale_items`
WHERE (`sale_items`.`product_id` = `p`.`id`)), 0) AS `total_sold`,
IFNULL((SELECT
SUM(`sale_items`.`quantity`)
FROM `sale_items`
WHERE ((`sale_items`.`product_id` = `p`.`id`) AND `sale_items`.`Sale_ID` IN (SELECT
`refunds`.`Sale_ID`
FROM `refunds`))), 0) AS `total_refund`
FROM ((`products` `p`
LEFT JOIN `cats` `c`
ON ((`c`.`ID` = `p`.`cat_id`)))
LEFT JOIN `suppliers` `s`
ON ((`s`.`ID` = `p`.`supplier_id`)))


This is the explain result



+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 20981 | |
| 2 | DERIVED | p | ALL | NULL | NULL | NULL | NULL | 20934 | |
| 2 | DERIVED | c | eq_ref | PRIMARY | PRIMARY | 4 | p.cat_id | 1 | |
| 2 | DERIVED | s | eq_ref | PRIMARY | PRIMARY | 4 | p.supplier_id | 1 | |
| 5 | DEPENDENT SUBQUERY | sale_items | ref | sales_items_product_id | sales_items_product_id | 5 | p.id | 33 | Using where |
| 6 | DEPENDENT SUBQUERY | refunds | index_subquery | IDX_refunds_sale_id | IDX_refunds_sale_id | 5 | func | 1 | Using index; Using where |
| 4 | DEPENDENT SUBQUERY | sale_items | ref | sales_items_product_id | sales_items_product_id | 5 | p.id | 33 | Using where |
| 3 | DEPENDENT SUBQUERY | stocks | ref | IDX_stocks_product_id | IDX_stocks_product_id | 5 | p.id | 1 | Using where |
+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------


I am expecting that the query takes less that 3s at most, but I cant seem to figure out the best way to optimize this query










share|improve this question





















  • 2





    What does EXPLAIN show?

    – PM 77-1
    Mar 28 at 21:15






  • 2





    For query-optimization questions please include the SHOW CREATE TABLE statements in your question.

    – Willem Renzema
    Mar 28 at 21:35






  • 1





    My first guess is that it's the derived tables which are costing you. Can you write your subqueries as regular outer joins ?

    – Neville Kuyt
    Mar 28 at 22:06






  • 1





    @Smith Yes it does. It will allow us to see the indexes you currently have, along with the column data types, to see if any are too large or are mismatched, along with other things critical to query optimization.

    – Willem Renzema
    Mar 28 at 22:56






  • 1





    If you have performance issues with subqueries in MySQL 5.5, the best advice is always to upgrade to a later version!

    – oysteing
    Mar 29 at 3:24

















2















I have a select query, that selects over 50k records from mysql 5.5 database at once, and this amount is expected to grow. The query contains multiple subquery which is taking over 120s to execute.



Initially some of the sale_items and stock tables didnt have more that the ID keys, so i added some more



SELECT
`p`.`id` AS `id`,
`p`.`Name` AS `Name`,
`p`.`Created` AS `Created`,
`p`.`Image` AS `Image`,
`s`.`company` AS `supplier`,
`s`.`ID` AS `supplier_id`,
`c`.`name` AS `category`,
IFNULL((SELECT
SUM(`stocks`.`Total_Quantity`)
FROM `stocks`
WHERE (`stocks`.`Product_ID` = `p`.`id`)), 0) AS `total_qty`,
IFNULL((SELECT
SUM(`sale_items`.`quantity`)
FROM `sale_items`
WHERE (`sale_items`.`product_id` = `p`.`id`)), 0) AS `total_sold`,
IFNULL((SELECT
SUM(`sale_items`.`quantity`)
FROM `sale_items`
WHERE ((`sale_items`.`product_id` = `p`.`id`) AND `sale_items`.`Sale_ID` IN (SELECT
`refunds`.`Sale_ID`
FROM `refunds`))), 0) AS `total_refund`
FROM ((`products` `p`
LEFT JOIN `cats` `c`
ON ((`c`.`ID` = `p`.`cat_id`)))
LEFT JOIN `suppliers` `s`
ON ((`s`.`ID` = `p`.`supplier_id`)))


This is the explain result



+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 20981 | |
| 2 | DERIVED | p | ALL | NULL | NULL | NULL | NULL | 20934 | |
| 2 | DERIVED | c | eq_ref | PRIMARY | PRIMARY | 4 | p.cat_id | 1 | |
| 2 | DERIVED | s | eq_ref | PRIMARY | PRIMARY | 4 | p.supplier_id | 1 | |
| 5 | DEPENDENT SUBQUERY | sale_items | ref | sales_items_product_id | sales_items_product_id | 5 | p.id | 33 | Using where |
| 6 | DEPENDENT SUBQUERY | refunds | index_subquery | IDX_refunds_sale_id | IDX_refunds_sale_id | 5 | func | 1 | Using index; Using where |
| 4 | DEPENDENT SUBQUERY | sale_items | ref | sales_items_product_id | sales_items_product_id | 5 | p.id | 33 | Using where |
| 3 | DEPENDENT SUBQUERY | stocks | ref | IDX_stocks_product_id | IDX_stocks_product_id | 5 | p.id | 1 | Using where |
+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------


I am expecting that the query takes less that 3s at most, but I cant seem to figure out the best way to optimize this query










share|improve this question





















  • 2





    What does EXPLAIN show?

    – PM 77-1
    Mar 28 at 21:15






  • 2





    For query-optimization questions please include the SHOW CREATE TABLE statements in your question.

    – Willem Renzema
    Mar 28 at 21:35






  • 1





    My first guess is that it's the derived tables which are costing you. Can you write your subqueries as regular outer joins ?

    – Neville Kuyt
    Mar 28 at 22:06






  • 1





    @Smith Yes it does. It will allow us to see the indexes you currently have, along with the column data types, to see if any are too large or are mismatched, along with other things critical to query optimization.

    – Willem Renzema
    Mar 28 at 22:56






  • 1





    If you have performance issues with subqueries in MySQL 5.5, the best advice is always to upgrade to a later version!

    – oysteing
    Mar 29 at 3:24













2












2








2








I have a select query, that selects over 50k records from mysql 5.5 database at once, and this amount is expected to grow. The query contains multiple subquery which is taking over 120s to execute.



Initially some of the sale_items and stock tables didnt have more that the ID keys, so i added some more



SELECT
`p`.`id` AS `id`,
`p`.`Name` AS `Name`,
`p`.`Created` AS `Created`,
`p`.`Image` AS `Image`,
`s`.`company` AS `supplier`,
`s`.`ID` AS `supplier_id`,
`c`.`name` AS `category`,
IFNULL((SELECT
SUM(`stocks`.`Total_Quantity`)
FROM `stocks`
WHERE (`stocks`.`Product_ID` = `p`.`id`)), 0) AS `total_qty`,
IFNULL((SELECT
SUM(`sale_items`.`quantity`)
FROM `sale_items`
WHERE (`sale_items`.`product_id` = `p`.`id`)), 0) AS `total_sold`,
IFNULL((SELECT
SUM(`sale_items`.`quantity`)
FROM `sale_items`
WHERE ((`sale_items`.`product_id` = `p`.`id`) AND `sale_items`.`Sale_ID` IN (SELECT
`refunds`.`Sale_ID`
FROM `refunds`))), 0) AS `total_refund`
FROM ((`products` `p`
LEFT JOIN `cats` `c`
ON ((`c`.`ID` = `p`.`cat_id`)))
LEFT JOIN `suppliers` `s`
ON ((`s`.`ID` = `p`.`supplier_id`)))


This is the explain result



+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 20981 | |
| 2 | DERIVED | p | ALL | NULL | NULL | NULL | NULL | 20934 | |
| 2 | DERIVED | c | eq_ref | PRIMARY | PRIMARY | 4 | p.cat_id | 1 | |
| 2 | DERIVED | s | eq_ref | PRIMARY | PRIMARY | 4 | p.supplier_id | 1 | |
| 5 | DEPENDENT SUBQUERY | sale_items | ref | sales_items_product_id | sales_items_product_id | 5 | p.id | 33 | Using where |
| 6 | DEPENDENT SUBQUERY | refunds | index_subquery | IDX_refunds_sale_id | IDX_refunds_sale_id | 5 | func | 1 | Using index; Using where |
| 4 | DEPENDENT SUBQUERY | sale_items | ref | sales_items_product_id | sales_items_product_id | 5 | p.id | 33 | Using where |
| 3 | DEPENDENT SUBQUERY | stocks | ref | IDX_stocks_product_id | IDX_stocks_product_id | 5 | p.id | 1 | Using where |
+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------


I am expecting that the query takes less that 3s at most, but I cant seem to figure out the best way to optimize this query










share|improve this question
















I have a select query, that selects over 50k records from mysql 5.5 database at once, and this amount is expected to grow. The query contains multiple subquery which is taking over 120s to execute.



Initially some of the sale_items and stock tables didnt have more that the ID keys, so i added some more



SELECT
`p`.`id` AS `id`,
`p`.`Name` AS `Name`,
`p`.`Created` AS `Created`,
`p`.`Image` AS `Image`,
`s`.`company` AS `supplier`,
`s`.`ID` AS `supplier_id`,
`c`.`name` AS `category`,
IFNULL((SELECT
SUM(`stocks`.`Total_Quantity`)
FROM `stocks`
WHERE (`stocks`.`Product_ID` = `p`.`id`)), 0) AS `total_qty`,
IFNULL((SELECT
SUM(`sale_items`.`quantity`)
FROM `sale_items`
WHERE (`sale_items`.`product_id` = `p`.`id`)), 0) AS `total_sold`,
IFNULL((SELECT
SUM(`sale_items`.`quantity`)
FROM `sale_items`
WHERE ((`sale_items`.`product_id` = `p`.`id`) AND `sale_items`.`Sale_ID` IN (SELECT
`refunds`.`Sale_ID`
FROM `refunds`))), 0) AS `total_refund`
FROM ((`products` `p`
LEFT JOIN `cats` `c`
ON ((`c`.`ID` = `p`.`cat_id`)))
LEFT JOIN `suppliers` `s`
ON ((`s`.`ID` = `p`.`supplier_id`)))


This is the explain result



+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 20981 | |
| 2 | DERIVED | p | ALL | NULL | NULL | NULL | NULL | 20934 | |
| 2 | DERIVED | c | eq_ref | PRIMARY | PRIMARY | 4 | p.cat_id | 1 | |
| 2 | DERIVED | s | eq_ref | PRIMARY | PRIMARY | 4 | p.supplier_id | 1 | |
| 5 | DEPENDENT SUBQUERY | sale_items | ref | sales_items_product_id | sales_items_product_id | 5 | p.id | 33 | Using where |
| 6 | DEPENDENT SUBQUERY | refunds | index_subquery | IDX_refunds_sale_id | IDX_refunds_sale_id | 5 | func | 1 | Using index; Using where |
| 4 | DEPENDENT SUBQUERY | sale_items | ref | sales_items_product_id | sales_items_product_id | 5 | p.id | 33 | Using where |
| 3 | DEPENDENT SUBQUERY | stocks | ref | IDX_stocks_product_id | IDX_stocks_product_id | 5 | p.id | 1 | Using where |
+----+--------------------+------------+----------------+------------------------+------------------------+---------+---------------------------------


I am expecting that the query takes less that 3s at most, but I cant seem to figure out the best way to optimize this query







mysql sql query-optimization






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 18 at 21:47







Smith

















asked Mar 28 at 21:08









SmithSmith

3,14015 gold badges85 silver badges141 bronze badges




3,14015 gold badges85 silver badges141 bronze badges










  • 2





    What does EXPLAIN show?

    – PM 77-1
    Mar 28 at 21:15






  • 2





    For query-optimization questions please include the SHOW CREATE TABLE statements in your question.

    – Willem Renzema
    Mar 28 at 21:35






  • 1





    My first guess is that it's the derived tables which are costing you. Can you write your subqueries as regular outer joins ?

    – Neville Kuyt
    Mar 28 at 22:06






  • 1





    @Smith Yes it does. It will allow us to see the indexes you currently have, along with the column data types, to see if any are too large or are mismatched, along with other things critical to query optimization.

    – Willem Renzema
    Mar 28 at 22:56






  • 1





    If you have performance issues with subqueries in MySQL 5.5, the best advice is always to upgrade to a later version!

    – oysteing
    Mar 29 at 3:24












  • 2





    What does EXPLAIN show?

    – PM 77-1
    Mar 28 at 21:15






  • 2





    For query-optimization questions please include the SHOW CREATE TABLE statements in your question.

    – Willem Renzema
    Mar 28 at 21:35






  • 1





    My first guess is that it's the derived tables which are costing you. Can you write your subqueries as regular outer joins ?

    – Neville Kuyt
    Mar 28 at 22:06






  • 1





    @Smith Yes it does. It will allow us to see the indexes you currently have, along with the column data types, to see if any are too large or are mismatched, along with other things critical to query optimization.

    – Willem Renzema
    Mar 28 at 22:56






  • 1





    If you have performance issues with subqueries in MySQL 5.5, the best advice is always to upgrade to a later version!

    – oysteing
    Mar 29 at 3:24







2




2





What does EXPLAIN show?

– PM 77-1
Mar 28 at 21:15





What does EXPLAIN show?

– PM 77-1
Mar 28 at 21:15




2




2





For query-optimization questions please include the SHOW CREATE TABLE statements in your question.

– Willem Renzema
Mar 28 at 21:35





For query-optimization questions please include the SHOW CREATE TABLE statements in your question.

– Willem Renzema
Mar 28 at 21:35




1




1





My first guess is that it's the derived tables which are costing you. Can you write your subqueries as regular outer joins ?

– Neville Kuyt
Mar 28 at 22:06





My first guess is that it's the derived tables which are costing you. Can you write your subqueries as regular outer joins ?

– Neville Kuyt
Mar 28 at 22:06




1




1





@Smith Yes it does. It will allow us to see the indexes you currently have, along with the column data types, to see if any are too large or are mismatched, along with other things critical to query optimization.

– Willem Renzema
Mar 28 at 22:56





@Smith Yes it does. It will allow us to see the indexes you currently have, along with the column data types, to see if any are too large or are mismatched, along with other things critical to query optimization.

– Willem Renzema
Mar 28 at 22:56




1




1





If you have performance issues with subqueries in MySQL 5.5, the best advice is always to upgrade to a later version!

– oysteing
Mar 29 at 3:24





If you have performance issues with subqueries in MySQL 5.5, the best advice is always to upgrade to a later version!

– oysteing
Mar 29 at 3:24












1 Answer
1






active

oldest

votes


















2
















The query looks fine to me. You select all data and aggregate some of it. This takes time. Your explain plan shows there are indexes on the IDs, which is good. And at a first glance there is not much we seem to be able to do here...



What you can do, though, is provide covering indexes, i.e. indexes that contain all columns you need from a table, so the data can be taken from the index directly.



create index idx1 on cats(id, name);
create index idx2 on suppliers(id, company);
create index idx3 on stocks(product_id, total_quantity);
create index idx4 on sale_items(product_id, quantity, sale_id);


This can really boost your query.



What you can try About the query itself is to move the subqueries to the FROM clause. MySQL's optimizer is not great, so although it should get the same execution plan, it may well be that it favors the FROM clause.



SELECT
p.id,
p.name,
p.created,
p.image,
s.company as supplier,
s.id AS supplier_id,
c.name AS category,
COALESCE(st.total, 0) AS total_qty,
COALESCE(si.total, 0) AS total_sold,
COALESCE(si.refund, 0) AS total_refund
FROM products p
LEFT JOIN cats c ON c.id = p.cat_id
LEFT JOIN suppliers s ON s.id = p.supplier_id
LEFT JOIN
(
SELECT SUM(total_quantity) AS total
FROM stocks
GROUP BY product_id
) st ON st.product_id = p.id
LEFT JOIN
(
SELECT
SUM(quantity) AS total,
SUM(CASE WHEN sale_id IN (SELECT sale_id FROM refunds) THEN quantity END) as refund
FROM sale_items
GROUP BY product_id
) si ON si.product_id = p.id;


(If sale_id is unique in refunds, then you can even join it to sale_items. Again: this should usually not make a difference, but in MySQL it may still. MySQL was once notorious for treating IN clauses much worse than the FROM clause. This may not be the case anymore, I don't know. You can try - if refunds.sale_id is unique).






share|improve this answer



























  • How fast is the original query after adding the indexes? After reformulating this way? (That is, is this a new starting point for the Question?)

    – Rick James
    Apr 19 at 5:05












Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);














draft saved

draft discarded
















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55406863%2fi-need-to-optimize-mysql-select-query-or-make-it-faster%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2
















The query looks fine to me. You select all data and aggregate some of it. This takes time. Your explain plan shows there are indexes on the IDs, which is good. And at a first glance there is not much we seem to be able to do here...



What you can do, though, is provide covering indexes, i.e. indexes that contain all columns you need from a table, so the data can be taken from the index directly.



create index idx1 on cats(id, name);
create index idx2 on suppliers(id, company);
create index idx3 on stocks(product_id, total_quantity);
create index idx4 on sale_items(product_id, quantity, sale_id);


This can really boost your query.



What you can try About the query itself is to move the subqueries to the FROM clause. MySQL's optimizer is not great, so although it should get the same execution plan, it may well be that it favors the FROM clause.



SELECT
p.id,
p.name,
p.created,
p.image,
s.company as supplier,
s.id AS supplier_id,
c.name AS category,
COALESCE(st.total, 0) AS total_qty,
COALESCE(si.total, 0) AS total_sold,
COALESCE(si.refund, 0) AS total_refund
FROM products p
LEFT JOIN cats c ON c.id = p.cat_id
LEFT JOIN suppliers s ON s.id = p.supplier_id
LEFT JOIN
(
SELECT SUM(total_quantity) AS total
FROM stocks
GROUP BY product_id
) st ON st.product_id = p.id
LEFT JOIN
(
SELECT
SUM(quantity) AS total,
SUM(CASE WHEN sale_id IN (SELECT sale_id FROM refunds) THEN quantity END) as refund
FROM sale_items
GROUP BY product_id
) si ON si.product_id = p.id;


(If sale_id is unique in refunds, then you can even join it to sale_items. Again: this should usually not make a difference, but in MySQL it may still. MySQL was once notorious for treating IN clauses much worse than the FROM clause. This may not be the case anymore, I don't know. You can try - if refunds.sale_id is unique).






share|improve this answer



























  • How fast is the original query after adding the indexes? After reformulating this way? (That is, is this a new starting point for the Question?)

    – Rick James
    Apr 19 at 5:05















2
















The query looks fine to me. You select all data and aggregate some of it. This takes time. Your explain plan shows there are indexes on the IDs, which is good. And at a first glance there is not much we seem to be able to do here...



What you can do, though, is provide covering indexes, i.e. indexes that contain all columns you need from a table, so the data can be taken from the index directly.



create index idx1 on cats(id, name);
create index idx2 on suppliers(id, company);
create index idx3 on stocks(product_id, total_quantity);
create index idx4 on sale_items(product_id, quantity, sale_id);


This can really boost your query.



What you can try About the query itself is to move the subqueries to the FROM clause. MySQL's optimizer is not great, so although it should get the same execution plan, it may well be that it favors the FROM clause.



SELECT
p.id,
p.name,
p.created,
p.image,
s.company as supplier,
s.id AS supplier_id,
c.name AS category,
COALESCE(st.total, 0) AS total_qty,
COALESCE(si.total, 0) AS total_sold,
COALESCE(si.refund, 0) AS total_refund
FROM products p
LEFT JOIN cats c ON c.id = p.cat_id
LEFT JOIN suppliers s ON s.id = p.supplier_id
LEFT JOIN
(
SELECT SUM(total_quantity) AS total
FROM stocks
GROUP BY product_id
) st ON st.product_id = p.id
LEFT JOIN
(
SELECT
SUM(quantity) AS total,
SUM(CASE WHEN sale_id IN (SELECT sale_id FROM refunds) THEN quantity END) as refund
FROM sale_items
GROUP BY product_id
) si ON si.product_id = p.id;


(If sale_id is unique in refunds, then you can even join it to sale_items. Again: this should usually not make a difference, but in MySQL it may still. MySQL was once notorious for treating IN clauses much worse than the FROM clause. This may not be the case anymore, I don't know. You can try - if refunds.sale_id is unique).






share|improve this answer



























  • How fast is the original query after adding the indexes? After reformulating this way? (That is, is this a new starting point for the Question?)

    – Rick James
    Apr 19 at 5:05













2














2










2









The query looks fine to me. You select all data and aggregate some of it. This takes time. Your explain plan shows there are indexes on the IDs, which is good. And at a first glance there is not much we seem to be able to do here...



What you can do, though, is provide covering indexes, i.e. indexes that contain all columns you need from a table, so the data can be taken from the index directly.



create index idx1 on cats(id, name);
create index idx2 on suppliers(id, company);
create index idx3 on stocks(product_id, total_quantity);
create index idx4 on sale_items(product_id, quantity, sale_id);


This can really boost your query.



What you can try About the query itself is to move the subqueries to the FROM clause. MySQL's optimizer is not great, so although it should get the same execution plan, it may well be that it favors the FROM clause.



SELECT
p.id,
p.name,
p.created,
p.image,
s.company as supplier,
s.id AS supplier_id,
c.name AS category,
COALESCE(st.total, 0) AS total_qty,
COALESCE(si.total, 0) AS total_sold,
COALESCE(si.refund, 0) AS total_refund
FROM products p
LEFT JOIN cats c ON c.id = p.cat_id
LEFT JOIN suppliers s ON s.id = p.supplier_id
LEFT JOIN
(
SELECT SUM(total_quantity) AS total
FROM stocks
GROUP BY product_id
) st ON st.product_id = p.id
LEFT JOIN
(
SELECT
SUM(quantity) AS total,
SUM(CASE WHEN sale_id IN (SELECT sale_id FROM refunds) THEN quantity END) as refund
FROM sale_items
GROUP BY product_id
) si ON si.product_id = p.id;


(If sale_id is unique in refunds, then you can even join it to sale_items. Again: this should usually not make a difference, but in MySQL it may still. MySQL was once notorious for treating IN clauses much worse than the FROM clause. This may not be the case anymore, I don't know. You can try - if refunds.sale_id is unique).






share|improve this answer















The query looks fine to me. You select all data and aggregate some of it. This takes time. Your explain plan shows there are indexes on the IDs, which is good. And at a first glance there is not much we seem to be able to do here...



What you can do, though, is provide covering indexes, i.e. indexes that contain all columns you need from a table, so the data can be taken from the index directly.



create index idx1 on cats(id, name);
create index idx2 on suppliers(id, company);
create index idx3 on stocks(product_id, total_quantity);
create index idx4 on sale_items(product_id, quantity, sale_id);


This can really boost your query.



What you can try About the query itself is to move the subqueries to the FROM clause. MySQL's optimizer is not great, so although it should get the same execution plan, it may well be that it favors the FROM clause.



SELECT
p.id,
p.name,
p.created,
p.image,
s.company as supplier,
s.id AS supplier_id,
c.name AS category,
COALESCE(st.total, 0) AS total_qty,
COALESCE(si.total, 0) AS total_sold,
COALESCE(si.refund, 0) AS total_refund
FROM products p
LEFT JOIN cats c ON c.id = p.cat_id
LEFT JOIN suppliers s ON s.id = p.supplier_id
LEFT JOIN
(
SELECT SUM(total_quantity) AS total
FROM stocks
GROUP BY product_id
) st ON st.product_id = p.id
LEFT JOIN
(
SELECT
SUM(quantity) AS total,
SUM(CASE WHEN sale_id IN (SELECT sale_id FROM refunds) THEN quantity END) as refund
FROM sale_items
GROUP BY product_id
) si ON si.product_id = p.id;


(If sale_id is unique in refunds, then you can even join it to sale_items. Again: this should usually not make a difference, but in MySQL it may still. MySQL was once notorious for treating IN clauses much worse than the FROM clause. This may not be the case anymore, I don't know. You can try - if refunds.sale_id is unique).







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 28 at 22:07

























answered Mar 28 at 22:01









Thorsten KettnerThorsten Kettner

55.4k3 gold badges28 silver badges48 bronze badges




55.4k3 gold badges28 silver badges48 bronze badges















  • How fast is the original query after adding the indexes? After reformulating this way? (That is, is this a new starting point for the Question?)

    – Rick James
    Apr 19 at 5:05

















  • How fast is the original query after adding the indexes? After reformulating this way? (That is, is this a new starting point for the Question?)

    – Rick James
    Apr 19 at 5:05
















How fast is the original query after adding the indexes? After reformulating this way? (That is, is this a new starting point for the Question?)

– Rick James
Apr 19 at 5:05





How fast is the original query after adding the indexes? After reformulating this way? (That is, is this a new starting point for the Question?)

– Rick James
Apr 19 at 5:05


















draft saved

draft discarded















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55406863%2fi-need-to-optimize-mysql-select-query-or-make-it-faster%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript