You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 8f36f5d
Browse filesBrowse the repository at this point in the historyBrowse files
perf: fetch table indexes for a schema in one query, not one per table
`enrichColumnsWithKeyAndIndexMetadata` called `getTableIndexes` once per
table inside its loop. On a wide schema that is hundreds of serial round
trips, and it re-runs for every caller that misses the `databaseObjects`
cache.
Measured on a 567-table MySQL connection reached over an SSH tunnel,
`GET /api/connections/{id}/objects`:
before 152.66s / 196.30s on cache miss (~270ms per table)
after 1.09s - 1.50s on cache miss
cached 0.03-0.48s (unchanged)
Both pre-fix requests were abandoned by the client (nginx 499). Because
there is no stampede guard, a second caller arriving during the first
sweep starts its own full sweep, so retrying made it worse.
The fix mirrors what `loadForeignKeyColumns` already does one line above:
fetch the whole schema once and group in memory. Adds
`IntrospectionProvider.getAllTableIndexes` with a default implementation
that loops the existing per-table method, so a provider that does not
override it is unchanged, plus overrides for both shipped providers:
- MySQL: one INFORMATION_SCHEMA.STATISTICS query scoped to a single
TABLE_SCHEMA, so it stays bounded on a server hosting many databases.
- Postgres: the same joins and filters as the per-table query, with
`t.relname = ANY(?)` in place of `t.relname = ?`. Matching bare relnames
across schemas is deliberate — it is what the per-table path already does
for an unqualified name.
Behaviour preserved:
- Tables with no indexes map to an empty list, so callers can distinguish
"no indexes" from "not scanned" without a per-table fallback.
- Objects qualified with a schema other than the connection database still
take the per-table path, since the bulk query covers a single schema.
- A failed bulk fetch logs and falls back rather than dropping index flags.
Verification. The Postgres form was diffed against the per-table form on a
live database with EXCEPT ALL in both directions: 744 rows each, zero rows
differing either way, composite index column order preserved. Both engines
were then exercised end to end with index flags still populated (MySQL: 760
columns with a single-column index and 375 composite, of 4588; Postgres: 32
and 2, of 128) and no fallback warnings logged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dSdoA8UGq7PVyvEwWjPXM
0 commit comments