簡體   English   中英

如何使用嵌套連接優化此mysql查詢?

[英]How do I optimize this mysql query with nested joins?

以下是我需要優化的查詢。

SELECT
        UPPER(IFNULL(op.supplier_payment_method,s.default_payment_method)) AS Payment_Method,
        op.supplier_payment_date AS Payment_Date,
        Date_format(IFNULL(op.supplier_payment_date,op.ship_date),'%M %Y') AS Payment_Month,
        s.supplier_name AS Farm,
        op.sub_order_id AS Order_num,
        Date_format(op.ship_date,'%b-%d-%Y') AS Ship_Date,
        op.farm_credit AS Farm_Credit,
        op.credit_memo AS Credit_Memo,
        op.credit_description AS Credit_Description,
        opb.boxes AS Box_Type,
        CONCAT('$',FORMAT(op.box_charge,2)) AS Box_Charge,
        op.invoice_num AS Invoice_num,
        CONCAT('$',FORMAT(op.invoice_amt,2)) AS Invoice_Amt,
        CONCAT('$',FORMAT(op.total_invoice_amt,2)) AS Total_Invoice_Amt,
        CONCAT(op.UM_qty,' ',op.UM_type) AS St_Bu_Qty,
        op.PO_Product_Name AS Invoice_desc,
        CONCAT('$',FORMAT((op.price_um*op.um_qty),2)) AS Cost_product_cms,
        op.supplier_invoice_note AS Supplier_Invoice_Notes,
        CONCAT('$',FORMAT(op.cms_invoice_cost,2)) AS CMS_Invoice_diff,
        CONCAT('$',FORMAT(op.total_farm_cost,2)) AS Farm_Cost
    FROM 
        orders_products op
        INNER JOIN 
            suppliers s ON s.supplier_id = op.supplier_name
        LEFT JOIN
            (
                SELECT 
                    sub_order_id, 
                    GROUP_CONCAT(CONCAT(box_type_qty,' ',bo.box_option_name) SEPARATOR ', ') AS boxes
                FROM
                    order_products_boxes opb
                    INNER JOIN box_options bo ON bo.id=opb.box_type_id
                GROUP BY
                    opb.sub_order_id
            ) opb ON opb.sub_order_id = op.sub_order_id
    WHERE
        op.order_active=0
        AND op.ship_date>='2013-03-01'
        AND op.ship_date<='2013-04_01'
    ORDER BY op.ship_date DESC

如您所見,該查詢包含4個表,每個表包含大約20k-30k行。 因此,一旦我添加了子查詢,查詢就會變得異常緩慢。 僅提取500行記錄大約需要1.5分鍾。 有沒有辦法在單個查詢中加快處理速度?

SELECT
    UPPER(IFNULL(op.supplier_payment_method,s.default_payment_method)) AS Payment_Method,
    op.supplier_payment_date AS Payment_Date,
    Date_format(IFNULL(op.supplier_payment_date,op.ship_date),'%M %Y') AS Payment_Month,
    s.supplier_name AS Farm,
    op.sub_order_id AS Order_num,
    Date_format(op.ship_date,'%b-%d-%Y') AS Ship_Date,
    op.farm_credit AS Farm_Credit,
    op.credit_memo AS Credit_Memo,
    op.credit_description AS Credit_Description,
     (
            SELECT 
                GROUP_CONCAT(CONCAT(box_type_qty,' ',bo.box_option_name) SEPARATOR ', ') 
            FROM
                order_products_boxes opb
                INNER JOIN box_options bo ON bo.id=opb.box_type_id
            GROUP BY
                opb.sub_order_id
        ) AS Box_Type,
    CONCAT('$',FORMAT(op.box_charge,2)) AS Box_Charge,
    op.invoice_num AS Invoice_num,
    CONCAT('$',FORMAT(op.invoice_amt,2)) AS Invoice_Amt,
    CONCAT('$',FORMAT(op.total_invoice_amt,2)) AS Total_Invoice_Amt,
    CONCAT(op.UM_qty,' ',op.UM_type) AS St_Bu_Qty,
    op.PO_Product_Name AS Invoice_desc,
    CONCAT('$',FORMAT((op.price_um*op.um_qty),2)) AS Cost_product_cms,
    op.supplier_invoice_note AS Supplier_Invoice_Notes,
    CONCAT('$',FORMAT(op.cms_invoice_cost,2)) AS CMS_Invoice_diff,
    CONCAT('$',FORMAT(op.total_farm_cost,2)) AS Farm_Cost
FROM 
    orders_products op
    INNER JOIN 
        suppliers s ON s.supplier_id = op.supplier_name
    LEFT JOIN

                order_products_boxes opb (
                INNER JOIN box_options bo ON bo.id=opb.box_type_id
        ) opb ON opb.sub_order_id = op.sub_order_id
WHERE
    op.order_active=0
    AND op.ship_date>='2013-03-01'
    AND op.ship_date<='2013-04_01'
ORDER BY op.ship_date DESC

預先連接了子框選項的左聯接查詢正在查詢ENTIRE DATABASE FIRST,然后僅聯接到您在外部WHERE子句所限制的條件內的那些聯接。 可能需要付出更多的努力,但是將相同的外部條件引入內部查詢應該會有所幫助。 至於在每行的基礎上執行字段級sql-select可能是性能的殺手。

您只需要在“ FROM”子句中進行更改...

from
   orders_products op
      INNER JOIN suppliers s 
         ON op.supplier_name = s.supplier_id 
      LEFT JOIN
         ( SELECT 
                 opb2.sub_order_id, 
                 GROUP_CONCAT(CONCAT(box_type_qty,' ',bo.box_option_name) SEPARATOR ', ') AS boxes
              FROM
                 orders_products op2
                    JOIN order_products_boxes opb2
                       on op2.sub_order_id = opb2.sub_order_id
                       INNER JOIN box_options bo 
                          ON opb2.box_type_id = bo.id
              WHERE
                     op2.order_active = 0
                 AND op2.ship_date >= '2013-03-01'
                 AND op2.ship_date <= '2013-04_01'
              GROUP BY
                 opb2.sub_order_id  ) opb 
         ON op.sub_order_id = opb.sub_order_id
WHERE
       op.order_active = 0
   AND op.ship_date >= '2013-03-01'
   AND op.ship_date <= '2013-04_01'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM