Amr Mohamed
Amr Mohamed

Reputation: 1

Does the foreign key slow down the join query?

I have two databases test & test2. Both have the same tables(employees & salaries) and both have the same records. test2 database uses a foreign key and test database doesn't.

test structure

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 structure

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    |                |
+--------+---------+------+-----+---------+----------------+

I run the same join query on both databases

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

This is the output i get from test database which doesn't contain a foreign key

2844047 rows in set (3.25 sec)

This is the output i get from test2 database which contains a foreign key

2844047 rows in set (17.21 sec)

So does the foreign key slow down the join query?

Upvotes: 0

Views: 980

Answers (1)

Gordon Linoff
Gordon Linoff

Reputation: 1269923

Your empirical evidence suggests that in at least one case it does. So, if we believe your numbers, the answer is clearly "yes" -- and I assume you have ruled out other potential causes such as locks on the table or resource competition (actually the difference is pretty big). I presume that you want to know why.

In most databases, declaring a foreign key is about relational integrity. It would have no effect on the optimization of queries. The join conditions in the query would redundantly cover the same information.

However, MySQL does a bit more when a foreign key is declared. A foreign key declaration automatically creates an index on the columns being used. This is not standard behavior -- I'm not even sure if any other database does this.

Normally, an index would benefit performance. In this case, the optimizer has more choices on how to approach the query. For whatever reason, it is using a substandard execution plan.

You should be able to look at the explain plans and see a difference. The issue is that the optimizer has chosen the wrong plan. I would say that this is uncommon and should not dissuade you from using proper foreign key declarations in your databases.

Upvotes: 4

Related Questions