[13.x] Improve getForeignKeys performance on MariaDB/MySQL on servers with many databases

Merged
RM
19d ago
+34-2

This PR limits the foreign key lookup in to just the relevant table, whereas previously MariaDB would look through every database on the server to answer the query, only for the majority of the results to get thrown out.

Problem

I have a MariaDB server where I host many clones of the same db for different workspaces/worktrees. After every migration runs a post-migration script and calls getForeignKeys() once per model, and each call searches ALL of the databases.

This makes the script run for more than 10 minutes in an environment with 25 databases and around 10k tables total.

Solution

Appended a database and table filter to referential_constraints, in which MariaDB now only looks at the one database and table it needs. Where before it would scan ALL databases, it now only scans 1 database.

* Benchmark of one getForeignKeys() call:

QueryTime
No filter12–22 s
Only rc.constraint_schema added6.3 s
Only rc.table_name added0.036 s
Both (this PR)0.028 s

The produced result remains the same, both columns exists on MySQL 5.7+ and all supported MariaDB versions.
Tests were run on and succeeded on MySQL 5.7, 8.4, 9.7 and MariaDB 10.11 (with and without an explicit schema, including composite keys and cascade rules)

--

No breaking changes