[英]How to optimize slow MySQL query
我有以下MySQL查询,它需要很长时间才能执行:
SELECT `market`.`name` AS `Markets`, count(*) * `clicks`.`cost` AS `Rev`
FROM `clicks`
INNER JOIN markets ON `clicks`.`market_id`= `markets`.`id`
WHERE clicks.created_date = `date1`
GROUP BY `markets`.`id`
ORDER BY `Rev` DESC
最初它非常慢,但后来我删除了冗余日期功能。 仍然需要很长时间才能执行。 有什么解决方案吗?
查询说明:我从一个表和行数中选择市场名称乘以另一个表的成本。 市场ID在第一个表“点击”中定义,我从“市场”表中获取市场名称。 我进一步按照他们的ID对市场进行分组,然后通过Rev降序排序
您的查询是按功能滥用MySQL 部分组 。 您按市场进行分组,但有一个clicks.cost
列的clicks.cost
,它不包含在聚合中。 无论查询速度有多快,您都会得到错误的结果。
您可以按如下方式修改查询:
SELECT market.name AS Markets, subqry.Rev FROM (
SELECT market_id, SUM(cost) AS Rev
FROM clicks
WHERE created_date = 'some date'
GROUP BY market_id
) AS subqry
INNER JOIN markets ON subqry.market_id = markets.id
ORDER BY Rev DESC
确保结果正确后,请创建以下索引:
CREATE INDEX ix_clicks ON clicks (created_date, market_id, cost)
据推测,你打算:
SELECT m.name AS Markets, SUM(c.cost) AS `Rev`
FROM clicks c INNER JOIN
markets m
ON c.market_id = m.id
WHERE c.created_date = ?
GROUP BY m.name
ORDER BY Rev DESC;
这对性能没有帮助。 但是, clicks(created_date, market_id, cost)
索引clicks(created_date, market_id, cost)
可能会为您提供所需的性能。
如果这不起作用,那么试试这个:
SELECT m.name AS Markets,
(SELECT SUM(c.cost)
FROM clicks c
WHERE c.market_id = m.id AND c.created_date = ?
) AS `Rev`
FROM markets m
ORDER BY Rev DESC;
这将删除外部GROUP BY
,这可以获得很大的性能提升。 为此,索引应略有不同, clicks(market_id, created_date, cost)
。
我知道这不是问题的直接答案,如果你愿意,你可以向我投票(我理解人性,对另类思想家表现出仇恨)。
但是我要编写另外正确的方法来做这样的逻辑系统,我们每天都有大量的数据,而且我们必须在没有性能问题的情况下制作摘要报告。
不幸的是,这是时间序列数据。
它会增长并且会损失您的性能损失。
对于短期添加索引可能会解决您的问题。
但从长远来看 ,许多市场将出现,点击量将达到每天约100万 ,“索引解决方案” 并不是一个好的解决方案。
A)如果你做索引日期字段你会慢速插入。 因为它每次都会在后台执行索引更新程序。
B)如果您对分区表进行分区,那么在一段时间之后很难管理,因为拥有数百个分区是不好的,并且某些日常业务将为当前数据结构带来非常“不舒服”的任务,这将导致重新思考表模式。
解决方案是重新思考你的逻辑:
clicks
表(表不应该有索引以快速插入)。 clicks_by_markets
, clicks_by_markets_yearly
, clicks_by_markets_weekly
, clicks_by_markets_daily
另一个解决方案(没有Kafka):
clicks_raw
来放置请求数据而不进行处理。 clicks_raw
表并填充表格,如: clicks_by_markets
, clicks_by_markets_yearly
, clicks_by_markets_weekly
, clicks_by_markets_daily
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.