我有一个疑问:
SELECT `l`.`id`, `l`.`headline`, `l`.`description`, `l`.`image`, `l`.`campaign_id`, IF(l.required_impressions=0,0,1) AS sequence, (IFNULL(ROUND(COUNT(DISTINCT(lc.id)) / COUNT(DISTINCT(li.id)), 3) * 100, 0) * 0.3) + (l.cost * 0.7) AS `scales`, `c`.`name` AS `campaign`
FROM `app_links` AS `l`
INNER JOIN `app_campaigns` AS `c` ON c.id = l.campaign_id
LEFT JOIN `app_link_clicks` AS `lc` ON lc.link_id = l.id
LEFT JOIN `app_link_impressions` AS `li` ON li.link_id = l.id
LEFT JOIN `app_links_categories` AS `lcat` ON l.id = lcat.link_id
LEFT JOIN `app_links_countries` AS `lcou` ON l.id = lcou.link_id
WHERE lcat.category_id IN(3,7,14)
AND lcou.country_id IN(89,147,124,131,259,197,88)
GROUP BY `l`.`id`
ORDER BY sequence DESC, `scales` DESC
LIMIT 6
EXPLAIN查询返回:
您对如何优化查询有什么想法吗?现在需要大约 0.6 秒,所以相当长:/
最佳答案
只要你指的是lcat
和lcou
在 WHERE
子句将它们加入 LEFT
是没有意义的加入。
所以我的建议是:
- 更改
LEFT JOIN
对于lcat
和lcou
至INNER JOIN
- 将这 2 个连接移至上方,以便全部
INNER JOIN
s 一开始 - 移动
lcat
和lcou
向记者提出条件ON
子句(这不会改变任何内容,但会更具可读性) - 创建组合
link_id + country_id
和link_id + category_id
索引 - 如您所见 - mysql 优化器更改了表连接的顺序,因此
app_links
在中间连接起来,看起来像app_links
是 myisam (这只是基于campaign_id
看起来不像聚集索引这一事实的猜测)。如果是这样 - 尝试添加化合物campaign_id + id
也为其建立索引
PS:进行上述更改并提供新的执行计划
PPS:为查询中的所有表提供架构
关于mysql - 优化sql查询运行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16564493/