Skip to content

Use high speed strategy for LuceneTopNSourceOperator#142128

Merged
carlosdelest merged 8 commits intoelastic:mainfrom
carlosdelest:enhancement/esql-lucene-top-n-data-partition-strategy
Feb 11, 2026
Merged

Use high speed strategy for LuceneTopNSourceOperator#142128
carlosdelest merged 8 commits intoelastic:mainfrom
carlosdelest:enhancement/esql-lucene-top-n-data-partition-strategy

Conversation

@carlosdelest
Copy link
Member

@carlosdelest carlosdelest commented Feb 9, 2026

Currently, LuceneTopNSourceOperator uses SHARD as auto strategy. This makes performance worse than the Query DSL when multiple segments are used, as SHARD does not parallelize queries.

This change uses LuceneSourceOperator::highSpeedAutoStrategy to allow parallelism based on the rules for high speed strategy described there:

  • Use SHARD for match none
  • Use DOC for match all
  • Use SEGMENT for other queries
  • Examine boolean queries, and use SHARD if any query should use it, SEGMENT if any query should use it and no SHARD queries exist, or DOC in case all queries should use it.

Closes #141770

@carlosdelest carlosdelest added >enhancement :Analytics/ES|QL AKA ESQL Team:Search Relevance Meta label for the Search Relevance team in Elasticsearch :Search Relevance/ES|QL Search functionality in ES|QL labels Feb 9, 2026
@carlosdelest carlosdelest marked this pull request as ready for review February 9, 2026 17:36
@elasticsearchmachine elasticsearchmachine added the Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) label Feb 9, 2026
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-analytical-engine (Team:Analytics)

@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-search-relevance (Team:Search Relevance)

@benwtrent
Copy link
Member

Drive by,

I don't know how the per-segment collection parallelism to work, but the query path will combine very tiny segments together as the cost of simply using threading for those tiny chunks of work isn't worth it.

Is something like that at work here? If not, expect the 1 worker == 1 segment logic to be harmful in indices with tiny segments (e.g. <100s of documents).

@carlosdelest
Copy link
Member Author

carlosdelest commented Feb 10, 2026

I don't know how the per-segment collection parallelism to work, but the query path will combine very tiny segments together as the cost of simply using threading for those tiny chunks of work isn't worth it.

@benwtrent there is indeed a grouping of smaller segments, please check DataPartitioning:

    /**
     * Make one partition per shard. This is generally the slowest option, but it
     * has the lowest CPU overhead.
     */
    SHARD,

    /**
     * Partition on segment boundaries, this doesn't allow forking to as many CPUs
     * as {@link #DOC} but it has much lower overhead.
     * <p>
     * It packs segments smaller than {@link LuceneSliceQueue#MAX_DOCS_PER_SLICE}
     * docs together into a partition. Larger segments get their own partition.
     * Each slice contains no more than {@link LuceneSliceQueue#MAX_SEGMENTS_PER_SLICE}.
     */
    SEGMENT,

    /**
     * Partitions into dynamic-sized slices to improve CPU utilization while keeping overhead low.
     * This approach is more flexible than {@link #SEGMENT} and works as follows:
     *
     * <ol>
     *   <li>The slice size starts from a desired size based on {@code task_concurrency} but is capped
     *       at around {@link LuceneSliceQueue#MAX_DOCS_PER_SLICE}. This prevents poor CPU usage when
     *       matching documents are clustered together.</li>
     *   <li>For small and medium segments (less than five times the desired slice size), it uses a
     *       slightly different {@link #SEGMENT} strategy, which also splits segments that are larger
     *       than the desired size. See {@link org.apache.lucene.search.IndexSearcher#slices(List, int, int, boolean)}.</li>
     *   <li>For very large segments, multiple segments are not combined into a single slice. This allows
     *       one driver to process an entire large segment until other drivers steal the work after finishing
     *       their own tasks. See {@link LuceneSliceQueue#nextSlice(LuceneSlice)}.</li>
     * </ol>
     */
    DOC;

Copy link
Member

@nik9000 nik9000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is faster for y'all I'm all for it.

It's probably worth explaining you why never use the lowOverheadAutoStrategy. You don't want it because you have to scan all the documents with topn.

private static final Logger logger = LogManager.getLogger(EsPhysicalOperationProviders.class);

// LuceneTopNSourceOperator auto strategy
private static final DataPartitioning.AutoStrategy TOP_N_AUTO_STRATEGY = unusedLimit -> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably make this a static method and reference it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done and documented using high speed in 45f70c3

@carlosdelest carlosdelest merged commit f1ed358 into elastic:main Feb 11, 2026
35 checks passed
carlosdelest added a commit to carlosdelest/elasticsearch that referenced this pull request Feb 13, 2026
sidosera pushed a commit to sidosera/elasticsearch that referenced this pull request Feb 13, 2026
costin pushed a commit to costin/elasticsearch that referenced this pull request Feb 16, 2026
…142128)

* First version, use highSpeedAutoStrategy

* Use highSpeedAutoStrategy

* Fix tests to take into account new partitioning

* Fix tests

* [CI] Auto commit changes from spotless

* Use a static method for strategy and document it

---------

Co-authored-by: elasticsearchmachine <infra-root+elasticsearchmachine@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Analytics/ES|QL AKA ESQL >enhancement :Search Relevance/ES|QL Search functionality in ES|QL Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) Team:Search Relevance Meta label for the Search Relevance team in Elasticsearch v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ES|QL - Improve data partition strategy for search use cases

4 participants