2016-08-03 83 views
0

我有一個查詢從product表(第一選擇)獲取產品描述,然後將其減去以下子查詢語句以獲取no。剩餘庫存的:使用多個子查詢連接優化查詢

inventory表(第2次)購買的每個產品的-sum

sales_detail表(第三)銷售的每個產品

每個產品的-sum的-sum轉移到另一個在stock_transfer表分支(4)

是得到了在damaged_product表(五)破壞每個產品的-sum

的問題是每次THI查詢加載時,它會全部搜索所有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; 

回答

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可以使用索引進行關聯子查詢中的聚合。

我知道你也有計算值。您可能需要在外部查詢中執行這些計算,從而實現子查詢的額外實現。

+0

感謝提示@Gordon Linoff!我會嘗試一下,並在完成測試後將其標記爲已接受 –