遇到我无法获得的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时,我可以看到其中一些查询正在运行,其中一些已经运行了很长时间(最多几分钟)。
查询中的表都包含所有相关列的索引(即表匹配的列)。
表格大小:
知道出了什么问题以及如何解决它?
更新:我已将查询转换为显式联接:
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
没有用。查询仍然需要很长时间才能执行。
答案 0 :(得分:1)
csb
以任意顺序需要INDEX(shopbikeid, category_id)
。如果categoriesshopbikes
是多对多映射表,您是否遵循了所有建议here?
sb
按此顺序需要INDEX(brand, dkprice)
。
我认为AND dkprice IS NOT NULL
对AND 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)