pingcap / pingcap/tidb

Adding a Foreign Key to empty tables is slow

Open
#65,753 8 comments 0 reactions 0 assignees View on GitHub
severity/moderate sig/sql-infra type/bug type/performance
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

3 ways of adding a foreign key
1. Create two tables then add a foreign key
2. Create two tables with the foreign key part of the table definition
3. Create two tables then add a foreign key, but with FK checks disabled.

For test 1:
| Time | Operation |
|---|---|
| 0.074 sec | CREATE TABLE t1 |
| 0.168 sec | CREATE TABLE t2 |
| 0.691 sec | ALTER TABLE t2 ADD FOREIGN KEY |

For test 2:
| Time | Operation |
|---|---|
| 0.159 sec | CREATE TABLE t1 |
| 0.110 sec | CREATE TABLE t2 (with FK) |

For test 3:
| Time | Operation |
|---|---|
| 0.160 sec | CREATE TABLE t1 |
| 0.076 sec | CREATE TABLE t2 |
| 0.520 sec | ALTER TABLE t2 ADD FOREIGN KEY (fk checks disabled)|

### 1. Minimal reproduce step (Required)

This is on a TiDB cluster with `tidb_enable_foreign_key=ON`

```sql
-- test 1
create table t1 (id int primary key);
create table t2 (id int primary key, t1_id int);
alter table t2 add constraint fk_t1 foreign key (t1_id) references t1 (id);
drop table t2,t1;

-- test 2
create table t1 (id int primary key);
create table t2 (id int primary key, t1_id int, constraint fk_t1 foreign key (t1_id) references t1 (id));
drop table t2,t1;

-- test 3
create table t1 (id int primary key);
create table t2 (id int primary key, t1_id int);
set foreign_key_checks=off;
alter table t2 add constraint fk_t1 foreign key (t1_id) references t1 (id);
set foreign_key_checks=on;
```

### 2. What did you expect to see? (Required)

Adding a foreign key between two empty tables should be fast.

### 3. What did you see instead (Required)

```
mysql-8.0.11-TiDB-v8.5.5 [test]> create table t1 (id int primary key);
Query OK, 0 rows affected (0.074 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]> create table t2 (id int primary key, t1_id int);
Query OK, 0 rows affected (0.168 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]> alter table t2 add constraint fk_t1 foreign key (t1_id) references t1 (id);
Query OK, 0 rows affected (0.691 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]>
mysql-8.0.11-TiDB-v8.5.5 [test]> drop table t2,t1;
Query OK, 0 rows affected (0.341 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]> create table t1 (id int primary key);
Query OK, 0 rows affected (0.159 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]> create table t2 (id int primary key, t1_id int, constraint fk_t1 foreign key (t1_id) references t1 (id));
Query OK, 0 rows affected (0.110 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]>
mysql-8.0.11-TiDB-v8.5.5 [test]> drop table t2,t1;
Query OK, 0 rows affected (0.318 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]> create table t1 (id int primary key);
Query OK, 0 rows affected (0.160 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]> create table t2 (id int primary key, t1_id int);
Query OK, 0 rows affected (0.076 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]> set foreign_key_checks=off;
Query OK, 0 rows affected (0.001 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]> alter table t2 add constraint fk_t1 foreign key (t1_id) references t1 (id);
Query OK, 0 rows affected (0.520 sec)

mysql-8.0.11-TiDB-v8.5.5 [test]> set foreign_key_checks=on;
Query OK, 0 rows affected (0.001 sec)
```
### 4. What is your TiDB version? (Required)

```
Release Version: v8.5.5
Edition: Community
Git Commit Hash: 1fa258b833ff113883beeba40bc130be7ce66610
Git Branch: HEAD
UTC Build Time: 2026-01-14 22:20:57
GoVersion: go1.25.5
Race Enabled: false
Check Table Before Drop: false
Store: tikv
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.