Home > other >  Mysql query performance improvement for inventory calculation
Mysql query performance improvement for inventory calculation

Time:09-11

I have a database structure like this:

Table: purchase_items:

 --------------------- --------------- ------ ----- --------- ---------------- 
| Field               | Type          | Null | Key | Default | Extra          |
 --------------------- --------------- ------ ----- --------- ---------------- 
| id                  | bigint(110)   | NO   | PRI | NULL    | auto_increment |
| purchase_id         | int(11)       | NO   | MUL | NULL    |                |
| product_id          | int(11)       | NO   | MUL | NULL    |                |
| units               | varchar(100)  | YES  |     | NULL    |                |
 --------------------- --------------- ------ ----- --------- ---------------- 

Table: sales_items:

 ----------------------- -------------- ------ ----- --------- ---------------- 
| Field                 | Type         | Null | Key | Default | Extra          |
 ----------------------- -------------- ------ ----- --------- ---------------- 
| id                    | int(11)      | NO   | PRI | NULL    | auto_increment |
| sales_id              | int(11)      | YES  | MUL | NULL    |                |
| product_id            | int(11)      | NO   | MUL | NULL    |                |
| purchase_item_id      | bigint(100)  | NO   | MUL | NULL    |                |
| qty                   | varchar(55)  | YES  |     | NULL    |                |
 ----------------------- -------------- ------ ----- --------- ---------------- 

There is a sales_return_items table similar to sales_items

I used to get the inventory as following:

SELECT
    pi.id,
    pi.product_id,
    pi.units,
    (
        SELECT SUM(si.qty) FROM sales_items si WHERE si.purchase_item_id = pi.id
    ) as sales_qty,
    (
        SELECT SUM(sri.qty) FROM sales_return_items sri WHERE sri.purchase_item_id = pi.id
    ) as sales_return_qty
FROM purchase_items pi

Above query used to get me the desired results.

But after adding a little more data error showing "request timeout" or taking more than 10 minutes to load the page.

My question is: How can I improve this query for performance?

CodePudding user response:

You could convert the correlated subqueries to joins:

SELECT
    pi.id,
    pi.product_id,
    pi.units,
    COALESCE(si.qty, 0) AS sales_qty,
    COALESCE(sri.qty, 0) AS sales_return_qty
FROM purchase_items pi
LEFT JOIN
(
    SELECT purchase_item_id, SUM(qty) AS qty 
    FROM sales_items
    GROUP BY purchase_item_id
) si
    ON si.purchase_item_id = pi.id
LEFT JOIN
(
    SELECT purchase_item_id, SUM(qty) AS qty
    FROM sales_return_items
    GROUP BY purchase_item_id
) sri
    ON sri.purchase_item_id = pi.id
GROUP BY
    pi.id;
  • Related