[英]SQL query: Speed up for huge tables
我们有一个包含大约25,000,000行的表,称为'events',具有以下模式:
TABLE events
- campaign_id : int(10)
- city : varchar(60)
- country_code : varchar(2)
以下查询需要很长时间(> 2000秒):
SELECT COUNT(*) AS counted_events, country_code
FROM events
WHERE campaign_id` in (597)
GROUPY BY city, country_code
ORDER BY counted_events
我们发现这是因为GROUP BY
部分。
已经使用了(campaign_id, city, country_code)
上的索引idx_campaign_id_city_country_code。
也许有人可以提出一个很好的解决方案来加快速度?
更新:
'Explain'表明,在许多可能的索引中,MySql使用了这个:'idx_campaign_id_city_country_code',对于它显示的行:'471304'和'Extra'它显示:'使用where; 使用临时; 使用filesort' -
这是EXPLAIN的整个结果:
更新:
好的,我认为它已经解决了:
再次查看粘贴的查询,我意识到我忘记在这里提到SELECT中还有一个名为'country_name'的列。 所以查询非常慢(包括country_name),但我只是把它留下来,现在查询的性能绝对可以。 抱歉,这个错误!
非常感谢您的所有有用的评论,我会提供所有好的答案! 有一些非常有用的补充,我可能也应用(如改变类型等)。
无论如何,没有看到EXPLAIN说这是一个长距离射击:
发布整个EXPLAIN输出
不要使用IN()
- 更好地使用:
WHERE campaign_id = 597
OR campaign_id = 231
OR ....
afaik IN()
很慢。
更新:像nik0lias一样评论 - IN()
比连接OR
条件更快。
一些想法:
鉴于表格的性质和大小,它将成为按国家/地区分区表格的理想选择。 这样,每个国家/地区的事件都将存储在不同的物理表中,即使它表现为虚拟大表
国家代码是字符串吗? 可能你有一个country_id,可以更容易排序。 (它可能会强制您创建或更改索引)
你真的在小组中使用这座城市吗?
问题是,MySQL不使用索引进行排序。 我不能说为什么,因为它应该。 可能是一个错误。
执行此查询的最佳策略是扫描索引的子树,其中event_id = 597。 由于索引按city_id排序,因此country_code不需要额外排序,扫描时可以计算行数。
因此索引已经是此查询的最佳选择。 MySQL没有正确使用它们。
我离线了解更多信息。 看起来这根本不是数据库问题,但是
从选择列表中删除country_name后,查询将恢复为仅索引扫描(EXPLAIN输出中的“using index”)并且速度非常快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.