外键会减慢联接查询的速度吗?

时间:2018-08-16 15:35:58

标签: mysql sql rdbms

我有两个数据库 test test2 。两者都有相同的表(员工和薪水),并且都有相同的记录。 test2 数据库使用外键,而 test 数据库不使用外键。

测试结构

test.employees
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| emp_id | int(11)     | NO   | PRI | NULL    |       |
| name   | varchar(30) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+

test.salaries
+--------+---------+------+-----+---------+----------------+
| Field  | Type    | Null | Key | Default | Extra          |
+--------+---------+------+-----+---------+----------------+
| id     | int(11) | NO   | PRI | NULL    | auto_increment |
| salary | int(11) | YES  |     | NULL    |                |
| emp_id | int(11) | NO   |     | NULL    |                |
+--------+---------+------+-----+---------+----------------+

test2结构

test2.employees
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| emp_id | int(11)     | NO   | PRI | NULL    |       |
| name   | varchar(30) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+

test2.salaries
+--------+---------+------+-----+---------+----------------+
| Field  | Type    | Null | Key | Default | Extra          |
+--------+---------+------+-----+---------+----------------+
| id     | int(11) | NO   | PRI | NULL    | auto_increment |
| salary | int(11) | YES  |     | NULL    |                |
| emp_id | int(11) | NO   | MUL | NULL    |                |
+--------+---------+------+-----+---------+----------------+

我在两个数据库上运行相同的联接查询

select * from employees inner join salaries on employees.emp_id=salaries.emp_id;

这是我从 test 数据库获得的输出,其中不包含外键

2844047 rows in set (3.25 sec)

这是我从 test2 数据库中获得的输出,该数据库包含外键

2844047 rows in set (17.21 sec)

外键会减慢联接查询的速度吗?

1 个答案:

答案 0 :(得分:4)

您的经验证据表明至少有一种情况确实如此。因此,如果我们相信您的数字,答案显然是“是”,并且我认为您已经排除了其他潜在原因,例如桌子锁定或资源竞争(实际上相差很大)。我想您想知道为什么。

在大多数数据库中,声明外键与关系完整性有关。它对查询的优化没有影响。查询中的join条件将多余地覆盖相同的信息。

但是,声明外键时,MySQL会做更多的事情。外键声明会在正在使用的列上自动创建索引。这不是标准行为-我什至不确定是否有其他数据库这样做。

通常情况下,索引会提高性能。在这种情况下,优化器在如何处理查询方面有更多选择。无论出于何种原因,它都使用了不合格的执行计划。

您应该能够查看explain计划并看到不同之处。问题是优化器选择了错误的计划。我会说这是不常见的,不应阻止您在数据库中使用适当的外键声明。

相关问题