You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-issues@jackrabbit.apache.org by "Thomas Mueller (Jira)" <ji...@apache.org> on 2026/09/23 09:06:00 UTC
[jira] [Assigned] (OAK-12401) ISCHILDNODE cost estimation for Lucene/Elastic property indexes is too high
[ https://issues.apache.org/jira/browse/OAK-12401?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Thomas Mueller reassigned OAK-12401:
------------------------------------
Assignee: Thomas Mueller
> ISCHILDNODE cost estimation for Lucene/Elastic property indexes is too high
> ---------------------------------------------------------------------------
>
> Key: OAK-12401
> URL: https://issues.apache.org/jira/browse/OAK-12401
> Project: Jackrabbit Oak
> Issue Type: Bug
> Components: indexing, query
> Reporter: Theia-Madalin Vlad
> Assignee: Thomas Mueller
> Priority: Major
>
> For a Lucene or Elastic property index, the estimated cost of an {{ISCHILDNODE}} (direct-children) restriction is only marginally lower than the cost of the equivalent {{ISDESCENDANTNODE}} (all-descendants) restriction, even though a direct-children query is far more selective.
> When evaluating a {{DIRECT_CHILDREN}} path restriction, the index adds an exact-depth condition to the generated query ({{:ancestors:<path>}} combined with an exact {{:depth}} term), so at runtime only the direct children are matched. However, the cost estimation in {{FulltextIndexPlanner}} does not take the depth restriction into account. It simply assumes:
> * {{DIRECT_CHILDREN}}: at most 50% of the estimated entries
> * all other (descendant) restrictions: at most 90% of the estimated entries
> So {{ISCHILDNODE}} is estimated at roughly half of {{ISDESCENDANTNODE}}, regardless of the actual tree shape. For a node that has a large number of descendants but only few direct children (a wide, deep subtree), this estimate is much too high.
> The practical consequence: the inflated index cost can exceed the cost of a plain traversal, so the query planner chooses to traverse instead of using the index. On subtrees where most descendants are not direct children, that traversal reads and discards a large number of nodes and is very slow.
> h4. Example (illustrative)
> {code:sql}
> SELECT * FROM [nt:unstructured] AS a
> WHERE ISCHILDNODE(a, '/content/a/b/c')
> ORDER BY LOWER(NAME(a)) ASC
> {code}
> With a matching Lucene index, the generated query restricts to {{:ancestors:/content/a/b/c}} plus an exact {{:depth}} term, but the estimated entry count is still ~50% of the full descendant count, and the plan may lose to {{traverse}}.
> h4. Expected
> The cost of an {{ISCHILDNODE}} restriction should be substantially lower than the cost of an {{ISDESCENDANTNODE}} restriction on the same path -- reflecting that direct children are typically a small fraction of all descendants -- so the index is preferred over traversal for these queries.
> h4. Pointer
> {{oak-search}} -- {{FulltextIndexPlanner}}, the {{DIRECT_CHILDREN}} branch of the path-restriction adjustment in the max-possible-doc-count estimation.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)