【问题标题】:Slow MySQL query with multiple sub-select joins具有多个子选择连接的慢 MySQL 查询
【发布时间】:2012-10-19 08:39:20
【问题描述】:

这一直困扰着我一整天:

我的这个查询运行良好,但在某些情况下速度很慢。解释结果告诉我 mysql 正在扫描 40000 行 3 次。该查询加入了大致相似的子选择,但都有些不同。

我该如何改进?

SET @lastchecktime = (SELECT max(tresults.StartTime) FROM tresults);
SELECT tresults.shopID
 , tshops.OfficialName
 , tresults.Price, tresults.starttime
 , Sub2.minprice
 , Sub2.StartTime
 , Sub3.daystoolow
 , (sub2.minprice/tsupplierproducts.lowestprice) -1 as afwijking
 , If(maxstarttime = @lastchecktime,'yes' ,'no') as notavailable     
FROM
  tresults
INNER JOIN tshops
ON tshops.shopID = tresults.shopID
inner JOIN (SELECT tresults.shopID
                 , max(tresults.StartTime) AS MaxStartTime
            FROM
            tresults
            WHERE
              tresults.pID = 7
              AND tresults.websiteID = 1
              AND tresults.StartTime BETWEEN "2012-08-01" AND "2012-12-01"              
            GROUP BY
              tresults.shopID) Sub1
ON tresults.StartTime = Sub1.MaxStartTime AND Sub1.shopID = tshops.shopID
INNER JOIN (SELECT tresults.shopID
             , tresults.StartTime
             , min(tresults.Price) AS minprice
        FROM
          tresults
        WHERE
          tresults.pID = 7
          AND tresults.websiteID = 1
          AND tresults.StartTime BETWEEN "2012-08-01" AND "2012-12-01"
        GROUP BY
          tresults.shopID) Sub2
ON Sub2.shopID = tshops.shopID
INNER JOIN (SELECT tresults.shopID
             , round(count(tresults.StartTime)/3,0) AS daystoolow
        FROM
          tsupplierproducts
        INNER JOIN tresults
        ON tsupplierproducts.pID = tresults.pID AND tresults.Price < tsupplierproducts.LowestPrice
        WHERE
          tresults.pID = 7
          AND tresults.websiteID = 1
          AND tresults.StartTime BETWEEN "2012-08-01" AND "2012-12-01"
          AND tsupplierproducts.supplierID = 2
        GROUP BY
          tresults.shopID) Sub3
ON Sub3.shopID = tshops.shopID
INNER JOIN tsupplierproducts
ON tsupplierproducts.pID = tresults.pID AND tsupplierproducts.supplierID = 2
WHERE
  tresults.pID = 7
  AND tresults.websiteID = 1
ORDER BY
notavailable desc, tresults.Price DESC

解释结果:

1, PRIMARY, tsupplierproducts, const, PRIMARY,fk_SupplierID,fk_pID, PRIMARY, 8, const,const, 1, Using temporary; Using filesort
1, PRIMARY, <derived4>, ALL, , , , , 27, 
1, PRIMARY, <derived2>, ALL, , , , , 43, Using where; Using join buffer
1, PRIMARY, <derived3>, ALL, , , , , 43, Using where; Using join buffer
1, PRIMARY, tshops, eq_ref, PRIMARY, PRIMARY, 4, Sub1.shopID, 1, Using where
1, PRIMARY, tresults, eq_ref,     PRIMARY,idxPID,idxWebsite,idxStartTimeASC,idxStartTimeDESC,fk_shopID, PRIMARY, 20, Sub1.MaxStartTime,const,Sub3.shopID,const, 1, 
4, DERIVED, tsupplierproducts, const, PRIMARY,fk_SupplierID,fk_pID, PRIMARY, 8, , 1, Using temporary; Using filesort
4, DERIVED, tresults, ref, PRIMARY,idxPID,idxWebsite,idxStartTimeASC,idxStartTimeDESC,     idxPID, 4, , 42048, Using     where
3, DERIVED, tresults, ref, PRIMARY,idxPID,idxWebsite,idxStartTimeASC,idxStartTimeDESC,     idxPID, 4, , 42048,     Using     where; Using temporary; Using filesort
2, DERIVED, tresults, ref, PRIMARY,idxPID,idxWebsite,idxStartTimeASC,idxStartTimeDESC, idxPID, 4, , 42048, Using where; Using index; Using temporary; Using filesort

任何帮助将不胜感激!

【问题讨论】:

    标签: mysql performance join


    【解决方案1】:

    我的建议是先删除子查询。

    【讨论】:

    • 这对我没有任何帮助。我需要上面查询的结果。删除子查询会给我带来不想要的结果。
    • 我认为 Vijay 的意思是用“正常”连接替换子查询,移动和调整 GROUP BY 位以适应主查询。您是否有一个更简单的示例,从概念上显示您正在尝试做什么?
    • 你是对的@davek.. 我建议删除子查询并用连接替换。
    • 普通连接是不够的。为了更容易理解:我有一个结果表,其中包含不同时间不同商店的不同产品价格。这会产生 3 列:时间、shopid、productID。我想对提供给定产品的所有商店以及日期范围内的最新价格和最低价格进行概述。我认为没有子连接就无法做到这一点。
    猜你喜欢
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 2014-08-28
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多