简体   繁体   English

MySQL查询非常慢

[英]Very slow MySQL query

This query takes a ridiculously long time to execute. 该查询需要花费很长的时间才能执行。 Duration / Fetch: 89.778 sec / 0.000 sec 持续时间/获取:89.778秒/0.000秒

Here's the query: 这是查询:

SELECT tblcompanyoperat.COPSCountry,
       AVG(tbldshipfees.Dship Total AnnualUSD) / 
                              AVG(tblcopsyearonyear.COPSMinWageUSD) AS Expr1
FROM (SELECT tblcopsyearonyear.Company NAME,
          tblcopsyearonyear.COPSCountry,
          MAX(tblcopsyearonyear.COPSFinYearEnd) AS MaxOfCOPSFinYearEnd
      FROM tblcopsyearonyear
      GROUP BY tblcopsyearonyear.Company NAME,
        tblcopsyearonyear.COPSCountry
      ORDER BY tblcopsyearonyear.COPSCountry,
        MAX(tblcopsyearonyear.COPSFinYearEnd)) AS qryCOPSLatestInfoYr,
     ((tblcompany 
       INNER JOIN tblcompanyoperat 
       ON tblcompany.CompName = tblcompanyoperat.Company NAME) 
      INNER JOIN tblcopsyearonyear 
      ON tblcompanyoperat.COMPOPID = tblcopsyearonyear.COMPOPID)
INNER JOIN (tbldirectorships 
            INNER JOIN tbldshipfees 
            ON tbldirectorships.DIRECTORSHIPSID = bldshipfees.DSHIPID) 
ON tblcompany.CompName = tbldirectorships.DSHIPCOMPANYLINK
WHERE blcompany.CompSector = 'Retail'
GROUP BY tblcompany.CompSector, 
         blcompanyoperat.COPSCountry,
         tbldshipfees.DSHIP Position
HAVING (AVG(tblcopsyearonyear.COPSMinWageUSD) IS NOT NULL
        AND tbldshipfees.DSHIP Position LIKE 'Chief%')
ORDER BY MAX(qryCOPSLatestInfoYr.MaxOfCOPSFinYearEnd);

What optimizations, apart from indexing, can I use to speed things up? 除了索引编制之外,我还可以使用哪些优化来加快处理速度? Explain extended output: 解释扩展输出:

id selet_type   table                 type possible_keys                                          key                         key_len  ref                                       rows filtered Extra
1, PRIMARY,     tblcompany,           ref, PRIMARY,tblSECTORStblCOMPANY,                          tblSECTORStblCOMPANY,       768,     const,                                    7,   100.00,  Using where; Using index; Using temporary; Using filesort
1, PRIMARY,     tblcompanyoperat,     ref, PRIMARY,CompanyName,                                   CompanyName,                768,     lrsmnc.tblcompany.CompName,               3,   100.00,  Using where
1, PRIMARY,     tblcopsyearonyear,    ref, PRIMARY,COMPOPID,                                      COMPOPID,                   4,       lrsmnc.tblcompanyoperat.COMPOPID,         1,   100.00, 
1, PRIMARY,     tbldirectorships,     ref, PRIMARY,DIRECTORSHIPSID,tblCOMPANYtblDIRECTORSHIPS,    tblCOMPANYtblDIRECTORSHIPS, 768,     lrsmnc.tblcompanyoperat.Company Name,     12,  100.00,  Using where; Using index
1, PRIMARY,     tbldshipfees,         ref, DSHIPID,tbldshipfeesDSHIPID,                           DSHIPID,                    4,       lrsmnc.tbldirectorships.DIRECTORSHIPSID,  1,   100.00, 
1, PRIMARY,     <derived2>,           ALL,                                                                                                                                       310, 100.00,  Using join buffer
2, DERIVED,     tblcopsyearonyear,    ALL,                                                                                                                                       523, 100.00,  Using temporary; Using filesort

Moving tbldshipfees.DSHIP Position LIKE 'Chief%' from the HAVING clause to the WHERE clause will improve execution time. tbldshipfees.DSHIP Position LIKE 'Chief%'HAVING子句移动到WHERE子句将缩短执行时间。 This is for two reasons. 这有两个原因。

First, no optimizations are done to items appearing in the HAVING clause for MySQL. 首先,对MySQL的HAVING子句中出现的项目不做任何优化。 This means that items may not be excluded using the index (as indicated in the EXPLAIN plan above. 这意味着可能无法使用索引排除项目(如上面的EXPLAIN计划中所示)。

Second, since the HAVING clause is applied immediately before returning the data to the client. 其次,由于在将数据返回给客户端之前立即应用了HAVING子句。 As a result, time is spent unnecessarily in all of the operations (aggregate functions, ORDER BYs, etc) before they are removed, increasing the amount of time taken to process. 结果,在删除所有操作(聚合函数,ORDER BY等)之前,它们不必要地花费了时间,从而增加了处理时间。

Reference: http://dev.mysql.com/doc/refman/5.5/en/select.html 参考: http : //dev.mysql.com/doc/refman/5.5/en/select.html

Additionally, for future maintenance reasons, changing from implicit joins to explicit joins would be recommended, as per X-Zero's comments. 另外,由于将来的维护原因,根据X-Zero的评论,建议从隐式联接更改为显式联接。 This could have additional performance benefits, as it reduces the optimization required by the database server. 这可能会带来其他性能优势,因为它减少了数据库服务器所需的优化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM