Repository navigation
perf(schemas): sample a table's columns across instances in one query - #153
Merged
Merged
Conversation
When a table's default instance holds no row, its columns were inferred by probing each named instance in turn, one query per instance until one answered rows. A schema with one instance per tenant paid one round trip per tenant for every empty table, each time the 30 s fields cache expired. One cross-instance sample answers the same rows in one query.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The DMS database console should stay fast on schemas with one instance per tenant. The Schemas page, the Overview, the health card, the data browser's table list and the row references all read
listSchemaSummaries(). It infers each table's columns from a 5-row sample, cached for 30 s. When a table's default instance held no row,sampleAnyInstanceprobed the named instances one query at a time until one answered rows. A table empty in every instance paid one round trip per tenant, on every cache miss.Change
src/service/introspect.ts: when the default instance holds no row, read the 5-row sample once throughCROSS_INSTANCEinstead of looping overlistSchemaInstances(). On MongoDB a cross-instance read adds no$match, so it is oneaggregatewith$limit: 5.Workload
Two isolated DMS runs (
dms-control up), each with its ownmongod: A onorigin/main, B on this branch. The playground'slinksschema has five tables, empty in every instance. Its named instances were raised to 3, 50 and 500 by rows in__antelope_instances. Each sample is one coldGET /api/database/schemas/after the 30 s caches expired. 7 samples per side, interleaved, with the order alternating each round. mongod's profiler counted the queries onlinks__*in each request.Evidence
Confirmed in an end-to-end benchmark.
linksPrimary number: a cold Schemas request at 500 named instances goes from 340.5 ms to 34.9 ms, 90% faster. At 3 instances the two sides overlap, so normal-size schemas see no measurable difference.
shopincluded, whose rows live only in itseuandusinstances.Impact
One cold request every 30 s for whoever opens a Schemas, Overview or data-browser page, per schema with named instances. On a 500-tenant schema that is about 0.3 s saved each time, and 1,226 fewer queries against the database. The impact is low, but it scales with the tenant count.
Behaviour note
The sample now spans tenants instead of coming from the first tenant, in creation order, that holds rows. Both are 5-row samples. When tenants store different types in one column, or a column only some tenants fill, the inferred type can differ. One case is a column typed
numberby tenant A's rows andstringby tenant B's. The design note (docs/design/redesign-v2-grill.md) says only that a named instance is sampled when the default one is empty. Keeping the exact old rule would take an ordered cross-instance read, which sorts the whole table on every cold request.Test
src/test/schemas-page.test.tsadds a tenanted schema whose only row is in a named instance. The test asserts itsamountcolumn is typednumber. It fails when sampling reads only the default instance:It passes on this branch, and
pnpm run checkspasses (Checks: 8 passed, 0 failed.).flowchart LR S[sampleAnyInstance] --> D{default instance has rows?} D -- yes --> R[use them] D -- no, before --> L[for each named instance: one query] --> R D -- no, after --> X[one CROSS_INSTANCE slice 0..5] --> RReadability
The function loses its loop and its call to
listSchemaInstances. The diff is 5 lines added and 9 removed.No overlap with #152, which changes
src/service/stagedSerialization.ts.Verify skill
verify-dms-databaseonae8afb3, with the featuresplanlists. The verdict isPASS+NOTES.The schemas check that a table whose rows live in named instances (
shop.order_items) lists its sampled columns still passes. Its wording described the old one-instance rule, soa50a4b0rewords it.