mysql - 通过多个子查询连接优化查询

标签 mysql sql join subquery left-join

我有一个查询,它从product表(第一个选择)获取产品描述,然后将其减去以下子查询语句以获得编号。剩余库存:

-库存表中购买的每种产品的总和(第二个)

-sales_detail 表中销售的每种产品的总和(第 3 个)

-stock_transfer 表中转移到另一个分支的每个产品的总和(第 4 个)

-damaging_product 表中每个损坏产品的总和(第 5 个)

问题是每次加载此查询时,它都会全面搜索所有 4 个表以获取 quantity 列的总和。而且随着时间的推移,存储的记录越多,查询就会变得越慢。有什么建议吗?

SELECT p.Id,p.Product_Name Product,p.Description, c.Category_Name Category,sc.Subcategory_Name Subcategory,s.Supplier_Name Supplier, p.Selling_Price `Unit Price`,i.Stocks,s.Sales, i.Stocks - IFNULL(s.Sales, 0) - IFNULL(t.Transfer, 0) - IFNULL(d.Damage, 0) AS Remaining

FROM (SELECT Id, Product_Name, Description, Selling_Price, Category_Id, Subcategory_Id, Supplier_Id       FROM product WHERE enable_flag = 1) p

LEFT OUTER JOIN(SELECT product_id, COALESCE(SUM(quantity), 0) AS Stocks
                FROM inventory
                WHERE enable_flag = 1 GROUP BY product_id) i ON p.Id = i.product_id

LEFT OUTER JOIN(SELECT product_id, COALESCE(SUM(quantity), 0) AS Sales
                FROM sales_detail
                WHERE enable_flag = 1 GROUP BY product_id) s USING(product_id)

LEFT OUTER JOIN(SELECT product_id, COALESCE(SUM(transfer_quantity), 0) AS Transfer
                FROM stock_transfer
                WHERE enable_flag = 1 GROUP BY product_id) t USING(product_id)

LEFT OUTER JOIN(SELECT product_id, COALESCE(SUM(damaged_quantity), 0) AS Damage
                FROM damaged_product
                WHERE enable_flag = 1 GROUP BY product_id) d USING(product_id)

JOIN Category c ON p.Category_Id=c.Id

JOIN Subcategory sc ON p.Subcategory_Id=sc.Id

JOIN Supplier s ON p.Supplier_Id=s.Id;

最佳答案

使用子查询会阻止使用索引,这会减慢查询速度。我建议像这样的查询:

SELECT p.*, sc.Subcategory_Name as Subcategory, s.Supplier_Name as Supplier,
       p.Selling_Price as `Unit Price`,
       (SELECT COALESCE(SUM(quantity), 0) 
        FROM inventory i
        WHERE s.enable_flag = 1 AND s.product_id = p.product_id
       ) as stocks,
       (SELECT COALESCE(SUM(quantity), 0) 
        FROM sales_detail sd
        WHERE i.enable_flag = 1 AND i.product_id = p.product_id
       ) as sales,
       (SELECT COALESCE(SUM(tansferquantity), 0) 
        FROM stock_transfer st
        WHERE st.enable_flag = 1 AND st.product_id = p.product_id
       ) as transfers,
       (SELECT COALESCE(SUM(damaged_quantity), 0) 
        FROM damage d
        WHERE d.enable_flag = 1 AND d.product_id = p.product_id
       ) as damaged
FROM product p JOIN
     Category c
     ON p.Category_Id = c.Id JOIN
     Subcategory sc
     ON p.Subcategory_Id = sc.Id JOIN
     Supplier s
     ON p.Supplier_Id = s.Id
WHERE p.enable_flag = 1;

为了提高性能,基础表需要在(product_id、enable_flag、quantity)上建立索引。 MySQL 可以在相关子查询中使用索引进行聚合。

我意识到你也有计算值。您可能需要在外部查询中执行这些计算,并利用子查询的附加具体化。

关于mysql - 通过多个子查询连接优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38744718/

相关文章:

mysql - sql select 查询不返回某些列

MySQL : Select all the rows except those having the specified values in columns

mysql - 加入多行并使用 MySQL(和 PHP)对它们求和

php - 在 PrestaShop 中创建新模块时,如何在不使用 mysql_connect 的情况下连接到数据库

php - mySQL:知道何时更新和何时插入?

mysql - 子查询在mysql中返回多于1行

mysql - 在另一个查询 MySQL 中使用来自一个查询的 SUM

php - 如何使一个计数函数在另一个计数函数中工作

mysql - 有条件 ORDER BY(列值)?

mysql - “加入”还是 'where not in()'?