Index suggestion for collection size is gated on autoIndex, so it only fires where it is redundant

Aperta Adatta ai principianti
#1,700 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
76/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
typescript
Ambito
database

Direzione di ricerca

Leggi ensureIndexForField in src/indexes/auto-index.ts, concentrandoti sulla guardia shouldAutoIndex e sulla sua unica chiamata a checkCollectionSizeForIndex. Esegui la riproduzione in TypeScript dell’issue con e senza autoIndex, quindi verifica che l’avviso relativo alle dimensioni della collection compaia solo quando l’indicizzazione manuale lascia assente un indice corrispondente e rimanga silenzioso per l’eager indexing.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

The collection-size index suggestion is gated on the wrong side of shouldAutoIndex. It is only reachable when autoIndex: 'eager' is set — where it is redundant, because the very next statement creates the index it asks for — and is unreachable when indexing is manual, which is the only situation where the advice has a recipient.

So the suggestion fires exactly where it is useless, and is silent exactly where it would be useful.

Details

ensureIndexForField in src/indexes/auto-index.ts (v0.6.17):

if (hasVirtualPropPath(fieldPath)) return
if (!shouldAutoIndex(collection)) return          // (1) eager-only from here on

const existingIndex = Array.from(collection.indexes.values()).find(...)
if (existingIndex) return                          // (2) index is genuinely absent

if (isDevModeEnabled()) {
  checkCollectionSizeForIndex(                     // (3) "you may want an index on x"
    collection.id || `unknown`,
    collection.size,
    fieldPath,
  )
}

try {
  collection.createIndex(...)                      // (4) ...creates that index

checkCollectionSizeForIndex has exactly one call site — this one. Consequences:

  • With autoIndex: 'eager': every field path first queried on a collection past collectionSizeThreshold logs Collection has N items. Queries on "url" may benefit from an index. / Add index: collection.createIndex((row) => row.url) — immediately before the library creates that index itself. It recurs after every gc cycle, because CollectionLifecycleManager.performCleanup empties the index map and the next compiled query rebuilds through the same path. Following the printed advice "fixes" it only by racing ahead of the check.
  • Without autoIndex: no collection-size suggestion is ever emitted, for any collection at any size. A manually-indexed collection missing an index on a hot field gets no size-based advice at all. slow-query still fires, but only once an average exceeds slowQueryThresholdMs (10ms), so it is reactive rather than predictive, and the join path's Join requires an index covers joins only — a plain where(eq(row.url, …)) full scan gets nothing before the fact.

Reproduction

import {
  createCollection,
  createLiveQueryCollection,
  eq,
  localOnlyCollectionOptions,
  BasicIndex,
} from '@tanstack/db'

const collection = createCollection({
  ...localOnlyCollectionOptions({ id: 'probe', getKey: (r: { id: string; url: string }) => r.id }),
  autoIndex: 'eager',
  defaultIndexType: BasicIndex,
})
collection.insert(
  Array.from({ length: 1100 }, (_, i) => ({ id: `n${i}`, url: `https://example.test/${i}` })),
)

const q = createLiveQueryCollection((qb) =>
  qb.from({ row: collection }).where(({ row }) => eq(row.url, 'https://example.test/7')),
)
await q.preload()

// console: Collection has 1100 items. Queries on "url" may benefit from an index. …
// collection.indexes → 1 (the index the warning asked for, created by the library)

Dropping autoIndex/defaultIndexType from the same script silences the suggestion entirely, while the collection now genuinely has no index — the inverse of the intended behaviour.

Suggested fix

Invert the guard rather than reorder the emit: run the size check when shouldAutoIndex(collection) is false (and no matching index exists), so it advises the users who must act on it, and stays quiet for collections the library is about to index itself. That is smaller than moving the emit below createIndex, and it restores the diagnostic instead of just quieting it.

Workaround

For anyone hitting the noise today, the public configureIndexDevMode seam works — drop collection-size and forward the rest, which leaves slow-query and the join full-scan warning intact:

configureIndexDevMode({
  onSuggestion: (suggestion) => {
    if (suggestion.type === 'collection-size') return
    console.warn(`[TanStack DB] [${suggestion.collectionId}] ${suggestion.message}`)
  },
})

Environment

@tanstack/db 0.6.17 (also present in 0.6.14), @tanstack/react-db 0.1.95, Node 22, verified against the published source in node_modules.

Aside: the index itself works well

Not part of the report, but useful context for anyone finding this issue while deciding whether to enable eager indexing. Same 22,830-row collection, indexed vs unindexed:

eager no autoIndex
where eq(url), 20 runs 5ms / 2ms 229ms / 201ms
leftJoin on id, 5 runs 62ms 217ms

The suggestion is noise; the auto-indexing it accompanies is doing real work.

Lingua principale
TypeScript
Stelle
3.9k
Fork
266
Merge medio
1g 4h
PR unite (30g)
52

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di TanStack/db

Tutte le issue di TanStack/db

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.