外键是否减慢了连接查询的速度?

d5vmydt9  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(491)

我有两个数据库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    |                |
+--------+---------+------+-----+---------+----------------+

测试2结构

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;

这是我从不包含外键的测试数据库得到的输出

2844047 rows in set (3.25 sec)

这是我从包含外键的test2数据库得到的输出

2844047 rows in set (17.21 sec)

那么外键是否会减慢连接查询的速度?

gblwokeq

gblwokeq1#

你的经验证据表明,至少有一种情况是这样的。因此,如果我们相信你的数字,答案显然是“是的”--我假设你已经排除了其他潜在的原因,如表上的锁或资源竞争(实际上差别很大)。我猜你想知道为什么。
在大多数数据库中,声明外键与关系完整性有关。它不会影响查询的优化。这个 join 查询中的条件将冗余地覆盖相同的信息。
然而,当声明一个外键时,mysql做的更多。外键声明会自动在正在使用的列上创建索引。这不是标准行为——我甚至不确定是否有其他数据库会这样做。
通常情况下,指数有利于业绩。在这种情况下,优化器在如何处理查询方面有更多的选择。不管出于什么原因,它都在使用不合格的执行计划。
你应该可以看看 explain 计划并看到不同。问题是优化器选择了错误的计划。我想说,这是不常见的,不应该劝阻您在数据库中使用正确的外键声明。

相关问题