Skip to content

[6.x] Only look among the entries found so far when a query narrows them further - #15891

Closed
DanielDarrenJones wants to merge 2 commits into
statamic:6.xfrom
DanielDarrenJones:perf/6x-stache-narrowed-wheres
Closed

DanielDarrenJones wants to merge 2 commits into
statamic:6.xfrom
DanielDarrenJones:perf/6x-stache-narrowed-wheres

Conversation

@DanielDarrenJones

Copy link
Copy Markdown
Contributor

Once an entry query has narrowed down to a few entries, every where after that still looks through the whole collection.

The Stache entry query builder works each where out over the full index of every collection being queried, and then intersects the result with the keys it has so far. A relationship field is the common case: whereIn('id', [...]) leaves a handful of entries, and then published, the status conditions and often site each go through every entry in the collection to arrive at a subset of that handful.

Now, when there are 250 keys or fewer so far and the next where is one whose result is intersected with them, a basic or whereIn condition only tests the index values of those keys. That carries into nested wheres. An orWhere, the other kinds of where, and larger sets of keys go the way they did. The keys that come back, and their order, are the same.

The two protected methods involved keep their signatures, so a query builder that extends this one and overrides them isn't affected.

Numbers

One query over a collection of 2,000 entries, average of 50 runs:

before after
whereIn('id', 170 ids) 0.31 ms 0.31 ms
... ->where('published', true) 1.00 ms 0.43 ms
... ->whereStatus('published') 1.82 ms 0.67 ms
... ->whereStatus('published')->where('site', 'en') 2.59 ms 0.74 ms

The time that's saved is in proportion to the size of the collection, so it's small on a site this size: of 35 pages and Control Panel requests timed, one (a localized page with several relationship fields) was faster, by 13% and 17% in two runs, and the rest were within noise. Every response was byte for byte the same.

Tests

A where after three entries have been found tests three values rather than the whole collection (fails without the change). Fourteen combinations of and, or, nested, whereIn, whereNotIn, status, like and ordering after a narrowing whereIn give the same results before and after.

@jasonvarga

Copy link
Copy Markdown
Member

Thanks for this but this one is adding complexity to gain maybe a few milliseconds. If you can show gains on a realistic site we can reconsider.

@jasonvarga jasonvarga closed this Nov 13, 2026
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.

2 participants