簡體   English   中英

MySQL查詢極慢

[英]MySQL Query extremely slow

以下查詢花費太多時間(此刻為0.8169sec)來顯示20個條目,但我找不到原因...

SELECT
        `Order`.ID,
        Order_Type.Description as OrderTypeDescription,
        `Order`.OrderType as OrderType,
        DATE_FORMAT(`Order`.InsertDate, '%d.%m.%Y') as OrderInsertDate,
        round(sum(Item_Price.Amount),2) as OrderAmount,
        c1.ID as buyerCustomerId,
        c2.ID as sellerCustomerId,
        c1.CompanyName as BuyerCompany,
        c2.CompanyName as SellerCompany,
        c1.ID as BuyerCustomer,
        c2.ID as SellerCustomer
    FROM `Order`
        INNER JOIN Order_Type ON Order_Type.ID=`Order`.OrderType
        INNER JOIN Customer as c1 ON c1.ID=`Order`.BuyerCustomer
        INNER JOIN Customer as c2 ON c2.ID=`Order`.SellerCustomer
        INNER JOIN Item ON Item.`Order`=`Order`.ID
        INNER JOIN Item_Price ON Item_Price.Item=Item.ID
    GROUP BY `Order`.ID,OrderType,OrderTypeDescription,buyerCustomerId,sellerCustomerId,BuyerCustomer,SellerCustomer
    ORDER BY `Order`.ID DESC
    LIMIT 20

EXPLAIN顯示以下輸出: http : //pastebin.com/5f9QYizq

我並不是非常擅長優化查詢,但是我認為性能不佳的原因可能是項目和item_price表上的聯接(和總和),因為兩個表中都有很多行(項目:16974, item_price:23981),因為每個項目都有一個或多個item_prices,它們總計為訂單金額。

任何想法如何使此查詢更快?

您可以嘗試使用相關子查詢,而不要使用group by

SELECT o.ID, ot.Description as OrderTypeDescription, ot.OrderType as OrderType,
       DATE_FORMAT(o.InsertDate, '%d.%m.%Y') as OrderInsertDate,
       (SELECT round(sum(ip.Amount), 2)
        FROM Item i INNER JOIN 
             Item_Price ip
             ON ip.Item = i.ID
        WHERE i.`Order` = o.ID
       ) as OrderAmount,
       c1.ID as buyerCustomerId,
       c2.ID as sellerCustomerId,
       c1.CompanyName as BuyerCompany,
       c2.CompanyName as SellerCompany,
       c1.ID as BuyerCustomer,
       c2.ID as SellerCustomer
FROM `Order` o INNER JOIN
      Order_Type ot
      ON ot.ID = o.OrderType INNER JOIN
      Customer c1
      ON c1.ID = o.BuyerCustomer INNER JOIN
      Customer c2
      ON c2.ID = `Order`.SellerCustomer
ORDER BY o.ID DESC
LIMIT 20;

這樣可以節省GROUP BY開銷。

您甚至可以將LIMIT移至子查詢,假設聯接未過濾任何行:

SELECT o.ID, ot.Description as OrderTypeDescription, ot.OrderType as OrderType,
       DATE_FORMAT(o.InsertDate, '%d.%m.%Y') as OrderInsertDate,
       (SELECT round(sum(ip.Amount), 2)
        FROM Item i INNER JOIN 
             Item_Price ip
             ON ip.Item = i.ID
        WHERE i.`Order` = o.ID
       ) as OrderAmount,
       c1.ID as buyerCustomerId,
       c2.ID as sellerCustomerId,
       c1.CompanyName as BuyerCompany,
       c2.CompanyName as SellerCompany,
       c1.ID as BuyerCustomer,
       c2.ID as SellerCustomer
FROM (SELECT o.*
      FROM `Order` o 
      ORDER BY o.id DESC
     ) o INNER JOIN
     Order_Type ot
     ON ot.ID = o.OrderType INNER JOIN
     Customer c1
     ON c1.ID = o.BuyerCustomer INNER JOIN
     Customer c2
     ON c2.ID = `Order`.SellerCustomer
ORDER BY o.ID DESC
LIMIT 20;

暫無
暫無

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

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