【问题标题】:MySQL Query extremely slowMySQL 查询极慢
【发布时间】:2016-03-22 00:38:45
【问题描述】:

以下查询需要太多时间(目前为 0.8169 秒)才能显示 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 和 item_price 表上的连接(和总和),因为两个表中都有很多行(item : 16974, item_price: 23981) 因为每件商品都有一个或多个 item_prices 合计为订单金额。

任何想法如何使这个查询更快?

【问题讨论】:

  • 如果这些列没有正确索引,您添加的每个JOIN 都有可能大大减慢您的查询速度。你确定你有所有这些案例的索引吗?还有一个名为 order 的表是一个错误的调用,因为它是一个保留字。

标签: mysql sql performance sum inner-join


【解决方案1】:

您可以尝试使用相关子查询而不是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;

【讨论】:

    猜你喜欢
    • 2012-05-03
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 1970-01-01
    相关资源
    最近更新 更多