MySQL性能问题用于简单的选择查询

时间:2016-07-25 12:44:27

标签: mysql sql performance

遇到我无法获得的MySQL性能问题。

此查询通常需要约1秒才能执行,但有时需要5分钟以上。

SELECT  sb.id AS id, sb.name AS name,
ROUND(sb.dkprice / 100, 0) AS price, bs.name AS shopname, country
    FROM  shopbikes sb, categoriesshopbikes csb, shops s
    WHERE  sb.id = csb.`shopbikeid`
      AND  csb.categoryid = 93
      AND  sb.brand = 'Ghost'
      AND  dkprice > 0
      AND  sb.dkprice IS NOT NULL
      AND  sb.`shopid` = s.id
    ORDER BY  dkprice
    LIMIT  1

对于不同的品牌,有时会有5-8个这样的查询同时运行。

当我执行SHOW FULL PROCESSLIST时,我可以看到其中一些查询正在运行,其中一些已经运行了很长时间(最多几分钟)。

查询中的表都包含所有相关列的索引(即表匹配的列)。

表格大小:

  • shopbikes = 600,000行
  • categoriesshopbikes = 100,000行
  • 商店= 100行

知道出了什么问题以及如何解决它?

更新:我已将查询转换为显式联接:

SELECT  sb.id AS id, sb.name AS NAME,
ROUND(sb.dkprice / 100, 0) AS price, s.name AS shopname, country
    FROM  shopbikes sb
    JOIN  categoriesshopbikes csb  ON (sb.id = csb.shopbikeid)
    JOIN  shops s  ON (sb.shopid = s.id)
    WHERE  csb.`categoryid` = 93
      AND  sb.`brand` = 'Cannondale'
      AND  dkprice > 0
      AND  dkprice IS NOT NULL
    ORDER BY  dkprice
    LIMIT  1 

没有用。查询仍然需要很长时间才能执行。

解释输出:http://i.imgur.com/kfMPBrd.png

2 个答案:

答案 0 :(得分:1)

csb以任意顺序需要INDEX(shopbikeid, category_id)。如果categoriesshopbikes是多对多映射表,您是否遵循了所有建议here

sb按此顺序需要INDEX(brand, dkprice)

我认为AND dkprice IS NOT NULLAND dkprice > 0来说是多余的。

答案 1 :(得分:0)

FROM shopbikes sb, categoriesshopbikes csb, shops s

我必须查看查询计划,但我认为这一行是问题所在。这种FROM子句可能会从列出的表中创建一个笛卡尔积(即600k * 100k * 100行)。

我猜测正确的JOIN条款会有所帮助

FROM shopbikes sb JOIN categoriesshopbikes csb ON (sb.id = csb.shopbikeid) JOIN shops s ON (sb.shopid = s.id)