Admin content-list search filter does an unindexable full-table scan #1774
khoinguyenpham04
announced in
Roadmap
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
This Roadmap discussion mirrors #1517: Admin content-list search filter does an unindexable full-table scan.
Use this discussion to upvote the roadmap item and discuss priority, use cases, and product feedback. Keep implementation tracking, reproduction details, and PR-specific feedback on the source issue.
Original Issue
Description
The admin content-list
qfilter (the search box on a collection list view) runs a substringLIKEthat cannot use any index, so it scans every non-deleted row in the locale on each search — including just to compute the result count. On large collections and on D1 (where this routes to the primary and reads every row) the rows-read / rows-returned ratio is terrible.The generated count query looks like:
Two things make it unindexable by construction:
%wildcard —pattern =%${term}%``, a substring match that no B-tree index can serve.lower(col)wraps the column, defeating the index onslug/titleregardless of the wildcard.Notably, EmDash already ships an FTS layer (fts5 + bm25,
packages/core/src/search/) that the content-list filter does not use. For collections withsearch_config.enabled, the list filter could be backed by FTS and fall back toLIKEotherwise.Source of the query:
ContentRepository.applySearchFilter/count:Steps to reproduce
resources).count(...)andfind(...)queries scan the full non-deleted set for the locale; rows-read greatly exceeds rows-returned.Environment
Logs / error output
No error — this is a performance/scalability issue (full scan, poor rows-read/returned ratio), not a crash.
Possible direction
LIKEotherwise.count()on search (e.g.LIMIT n+ "n+").Beta Was this translation helpful? Give feedback.
All reactions