我有一个查询从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;
答案 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可以在相关子查询中使用索引进行聚合。
我意识到你也有计算值。您可能需要在外部查询中执行这些计算,从而获得子查询的其他实现。