Skip to content

perf(find): resolve only the named design doc when use_index is given - #9268

Open
Crash-- wants to merge 1 commit into
apache:masterfrom
Crash--:perf/find-targeted-use_index
Open

perf(find): resolve only the named design doc when use_index is given#9268
Crash-- wants to merge 1 commit into
apache:masterfrom
Crash--:perf/find-targeted-use_index

Conversation

@Crash--

@Crash-- Crash-- commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Problem

find() always calls getIndexes(db), which does an allDocs over the whole
_design/ range with include_docs: true — loading and massaging every query
design doc on every find(), even when the caller already named the index via
use_index. The planner then walks all of them only to keep the one that was named.

On a database with many mango indexes (and clients that always pass use_index), this is overhead proportional to the number of design docs, repeated per query. On React Native it serializes into a multi-second stall on a large replica.

Fix

When use_index is present, fetch just that one design doc with
db.get('_design/<ddoc>') and build the index list from it. If anything is unexpected
(missing ddoc, non-query language, malformed views, or the named index doesn't satisfy
the request), fall back to the original full getIndexes() path — so results and error
behaviour are unchanged (the existing unknown_error / no_usable_index cases still
raise the same errors).

Ported to async/await to match current master; adds a test asserting a use_index find
returns the same docs as the unindexed find.

find() always called getIndexes(db), which does allDocs over the whole
'_design/' range with include_docs:true — loading and massaging EVERY query
design doc on every single find(), even when the caller already named the
index via use_index. The query planner then walks all of them only to keep
the one that was named. On a database with many mango indexes (and clients
such as cozy-pouch-link that always pass use_index), this is pure overhead
on the JS thread proportional to the number of design docs, repeated per
query.

When use_index is present, fetch just that one design doc with
db.get('_design/<ddoc>') and build the index list from it. If anything is
unexpected (missing ddoc, non-query language, malformed views, or the named
index does not satisfy the request), fall back to the original full
getIndexes() path so results and error behaviour are unchanged — the
existing "index does not exist" (unknown_error) and "index cannot be used"
(no_usable_index) cases still raise the same errors.

Adds a test asserting a use_index find returns the same docs as the
unindexed find.
Crash-- added a commit to linagora/twake-drive-mobile that referenced this pull request Jul 27, 2026
The four upstream perf fixes have merged and released, so the cozy-* patches
are no longer needed. Bump to the release that carries them and drop the two
interim patches:

- linagora/cozy-client#1697 (getById fast-path)
- linagora/cozy-client#1700 (seed dir fullpaths)
- linagora/cozy-client#1702 (native SQLite engine + mango hardening)

The native SQLiteQuery engine now ships in cozy-pouch-link@60.30.1, so the
platformReactNative queryEngine wiring keeps working against the release.

Still vendored via patch-package (not yet upstream-released):
- pouchdb-adapter-react-native-sqlite@4.1.3 (apache/pouchdb#89 fork)
- pouchdb-find@8.0.1 (apache/pouchdb#9268)
Crash-- added a commit to linagora/twake-drive-mobile that referenced this pull request Jul 27, 2026
Wire the first-sync performance work into the app ahead of the upstream
releases: apply the four fixes as patch-package patches and activate the
native SQLite query engine.

Each patch mirrors an upstream PR one-to-one:

- cozy-client+60.24.0     -> linagora/cozy-client#1697 (getById fast-path)
- cozy-pouch-link+60.24.2 -> linagora/cozy-client#1700 (seed dir fullpaths)
                             + linagora/cozy-client#1702 (native SQLite engine:
                               WAL, winningseq JOIN, scoped executeSQL catch)
- pouchdb-adapter-react-native-sqlite+4.1.3 -> apache/pouchdb#89 fork
                               (read-priority transaction queue)
- pouchdb-find+8.0.1      -> apache/pouchdb#9268 (targeted use_index)

platformReactNative sets queryEngine: SQLiteQuery so reads go through the
native engine instead of pouch-find. The cozy-* patches are interim and get
dropped once the upstream versions release and the deps are bumped.
Crash-- added a commit to linagora/twake-drive-mobile that referenced this pull request Jul 27, 2026
The four upstream perf fixes have merged and released, so the cozy-* patches
are no longer needed. Bump to the release that carries them and drop the two
interim patches:

- linagora/cozy-client#1697 (getById fast-path)
- linagora/cozy-client#1700 (seed dir fullpaths)
- linagora/cozy-client#1702 (native SQLite engine + mango hardening)

The native SQLiteQuery engine now ships in cozy-pouch-link@60.30.1, so the
platformReactNative queryEngine wiring keeps working against the release.

Still vendored via patch-package (not yet upstream-released):
- pouchdb-adapter-react-native-sqlite@4.1.3 (apache/pouchdb#89 fork)
- pouchdb-find@8.0.1 (apache/pouchdb#9268)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant