mysql - 优化sql查询运行时间

标签 mysql sql optimization

我有一个疑问:

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查询返回: enter image description here

您对如何优化查询有什么想法吗?现在需要大约 0.6 秒,所以相当长:/

最佳答案

只要你指的是lcatlcouWHERE子句将它们加入 LEFT 是没有意义的加入。

所以我的建议是:

  1. 更改LEFT JOIN对于 lcatlcouINNER JOIN
  2. 将这 2 个连接移至上方,以便全部 INNER JOIN s 一开始
  3. 移动lcatlcou向记者提出条件ON子句(这不会改变任何内容,但会更具可读性)
  4. 创建组合 link_id + country_idlink_id + category_id索引
  5. 如您所见 - mysql 优化器更改了表连接的顺序,因此 app_links在中间连接起来,看起来像 app_links是 myisam (这只是基于 campaign_id 看起来不像聚集索引这一事实的猜测)。如果是这样 - 尝试添加化合物 campaign_id + id也为其建立索引

PS:进行上述更改并提供新的执行计划

PPS:为查询中的所有表提供架构

关于mysql - 优化sql查询运行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16564493/

相关文章:

php - 具有依赖项计数的 Laravel 查询生成器

php - 检查多列上的重复行

c - 哪个更快 - 排序或乘以一个小的元素数组?

mysql - 检查列中是否有多个值

sql - 如何使用 GROUP BY 修改 SQL SELECT 请求

python - 优化 Python 中的函数以处理大块数据

python - 通过有序圆形航路点的最短路径

mysql - mysql表中多次插入,有些可能会重复

java - 我的浏览器中显示的可分页数据错误

php - 将搜索和替换限制为类别