使用多个子查询连接优化查询

时间:2016-08-03 13:13:39

标签: mysql sql join subquery left-join

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

- 在inventory表(第二)中购买的每种产品的总数

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

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

- 在damaged_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;

1 个答案:

答案 0 :(得分:2)

使用子查询可以防止使用索引,这会降低查询速度。我会建议一个像这样的查询:

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可以在相关子查询中使用索引进行聚合。

我意识到你也有计算值。您可能需要在外部查询中执行这些计算,从而获得子查询的其他实现。