MySQL与FK一对多加入很慢

时间:2017-02-06 21:21:47

标签: mysql

我有一个人员和公司表。每个People记录都有一个非空的FK Company_ID。我有大约130,000家公司和260万人的记录。

我在people.name上有一个全文索引,效果很好。这大约需要0.3秒:

SELECT DISTINCT `people`.`Name`
FROM mydb.`people`
WHERE match(`people`.`Name`) against('john')

以下是我从“show table create”运行的表定义和索引:

CREATE TABLE `companies` (
`Id` bigint(20) NOT NULL AUTO_INCREMENT,
`Name` longtext,
PRIMARY KEY (`Id`),
FULLTEXT KEY `companies_name_FT_IDX` (`Name`)
) ENGINE=InnoDB AUTO_INCREMENT=129590 DEFAULT CHARSET=utf8

CREATE TABLE `people` (
`Id` bigint(20) NOT NULL AUTO_INCREMENT,
`Name` longtext,
`Company_Id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`Id`),
KEY `IX_Company_Id` (`Company_Id`) USING HASH,
FULLTEXT KEY `people_name_FT_IDX` (`Name`),
CONSTRAINT `FK_People_Companies_Company_Id` FOREIGN KEY (`Company_Id`)       
REFERENCES `companies` (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=2640085 DEFAULT CHARSET=utf8

问题在于,通过ID与人和公司的加入需要超过16秒。

SELECT DISTINCT `companies`.`Id`, `companies`.`Name`, `people`.`Name`
FROM mydb.`companies`
INNER JOIN mydb.`people` ON mydb.`companies`.`Id` = mydb.`people`.`Company_Id` 
WHERE match(`people`.`Name`) against('john')

编辑: 在查看Workbench中的大量内容后,我看到innodb缓冲区在查询时间内最大化。我追踪到要在my.ini中设置(Windows)。它设置为8M,我把它撞到了1G并重新启动了mysql。我的查询现在运行得非常快。具体来说:innodb_buffer_pool_size = 1G

有没有理由MySQL默认资源如此之小?有什么方法可以使用Workbench为我的PC设置“推荐”值吗?通过浏览my.ini文件,似乎很可能还有更多设置可以提升。

谢谢。

2 个答案:

答案 0 :(得分:1)

我发现这篇文章是关于配置安装MySQL后我需要的性能设置: https://www.percona.com/blog/2014/01/28/10-mysql-performance-tuning-settings-after-installation/

这似乎正是我需要做的,以便从开箱即用的配置中提高MySQL的性能。

(谢谢Mike Nakis在我深入研究这个问题时为我提出了几个好主意。)

答案 1 :(得分:0)

旧版本的MySQL默认innodb_buffer_pool_size的关键设置为可怜的8M。这个曾经在各种论坛上引发了很多问题。然后他们将默认值提高到128M;摆脱了大部分可归因于该设置的问题。

如果你的RAM少于4GB,那1GB可能会非常危险。

如果您主要使用InnoDB,如果可用 RAM,则该值为70%。关于该主题的My blog