为什么mysql中的select查询速度如此之慢?
表模式为什么mysql中的select查询速度如此之慢?,mysql,sql,Mysql,Sql,表模式 数据库引擎是MyISAM 提交(约500000000行) id(int)-PK(索引) 项目标识(int)-FK[项目->标识](索引) 提交者id-FK[用户->id](索引) 项目(约3200万行) id(int)-PK(索引) 用户(约12000000行) id-PK(索引) 解释 SELECT COUNT(*) FROM commits WHERE committer_id = 30351173 上述查询在10秒内完成。 SELECT project_id , CO
数据库引擎是MyISAM 提交(约500000000行)
id(int)-PK(索引)
项目标识(int)-FK[项目->标识](索引)
提交者id-FK[用户->id](索引)
项目(约3200万行)
id(int)-PK(索引)
用户(约12000000行)
id-PK(索引)
解释
SELECT COUNT(*)
FROM commits
WHERE committer_id = 30351173
上述查询在10秒内完成。
SELECT project_id , COUNT(*) as commit_count
FROM commits
WHERE committer_id = 30351173
GROUP BY project_id
但是,上述查询未在2小时内完成(7200秒)
提交中的项目id
是完整的索引列,但速度太慢
为什么会这样
Q)如何加快第二次查询的速度?
附加的
SELECT project_id , COUNT(*) AS commit_count
FROM commits
WHERE committer_id = 1891264
GROUP BY project_id
我查询另一个committer\u id
是否已完成15秒。
SELECT project_id , COUNT(*) as commit_count
FROM commits
WHERE committer_id = 30351173
GROUP BY project_id
附加-2
EXPLAIN SELECT COUNT(*) FROM commits WHERE committer_id = 30351173
输出
输出
这是因为
分组
声明
SQL Server必须检查表中的每一行
项目id上的索引可能会解决此问题
alter table提交添加索引(提交者id) 您应该尝试一种覆盖索引,如
为什么?
您的查询:
- 从表中选择
project\u id
- 选择使用
committer\u id
- 使用
project\u id
where
子句(此处为committer\u id
)位于第一个位置的位置创建索引,您可以让MySQL在访问表之前快速将涉及的记录归零。一旦有了这些记录,MySQL就可以开始工作了但是如果索引中还有用于分组的信息,即project\u id
,MySQL甚至可以在访问表之前开始分组数据。最后,如果all索引上也存在其他信息(这里已经完成了,因为它与WHERE
使用的信息相同),MySQL根本不需要访问该表。按此顺序提供此信息的索引是此查询的覆盖索引
当然,这是更有利的,相对于完整表行,您使用的数据越小;显然,如果您有一个100 GB的表和一个75 GB的索引,那么性能增益很小。如果您有一个100 GB的表和1 GB的索引,您将获得一个巨大的胜利。特别是当1GB索引上的查询基数较低时(例如,提交者只负责1%的数据)。然后,您将读取10MB的数据,而不是100GB的数据,并且您不会相信性能的提高
获得索引后,您将执行以下操作:
SELECT project_id , COUNT(1) AS commit_count
FROM commits
WHERE committer_id = 1891264
GROUP BY project_id
这应该只在索引上运行
我说,试试看,因为维护索引也要付出代价。这种情况很可能是您加快了这个SELECT查询的速度,代价是降低了插入和更新的速度,因为它们需要管理索引和表
顺便说一句,通过使用COUNT(1),查询将不会显示在grep
搜索中,从而允许关注带有重要星号的查询
此外,当您进行此类测试时,请记住执行以下操作:
- 对慢速id的测试
- 在不同的id上进行测试
- 使用稍有不同的查询(例如,添加AS..alias)在slow_id上再次测试
(1) 这是如果您运行快速测试。否则,性能测试要比这复杂得多;Percona博客上有几篇关于这个主题的文章。真正重要的专栏是
committer\u id
。有索引吗?你把条件加进去了!为提交者id添加一个索引,它应该会加快速度。此外,相对于COUNT(*)
,您还可以计算每一行的唯一标识符,如果存在的话-认为您有id
?是的<代码>提交者id是索引(BTREE)列。外键用户->idPut解释在之前选择并将输出粘贴到此处。谢谢。OP使用的是MySQL,而不是SQL Server。无论如何,WHERE
子句很可能是此处的关键部分,这意味着committer\u id
列上的索引对您的答复至关重要。我会尽力让你知道结果。
SELECT project_id , COUNT(1) AS commit_count
FROM commits
WHERE committer_id = 1891264
GROUP BY project_id