Re: Solr performance degradation for collapse queries with string sort fields after migration from Solr 8.11.2 to Solr 9.10.1
Bartosz Fidrysiak <[email protected]> Thu, 25 Jun 2026 09:16:15 +0200
| Newsgroups | gmane.comp.jakarta.lucene.user |
|---|---|
| Message-ID | <CAF4YFthwMT+4=CLJkOAVEtUhw+o9TxvVsApYYX8PJU6di7dzsw@mail.gmail.com> |
--0000000000003644b006550ec5b0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable We operate a generic search tool whose primary use case involves collapsing and expanding documents based on user-provided keywords and filter queries. Since requests use Solr cursors, iterating through large result sets is a common pattern. We do not control how the user-provided keywords and filter queries narrow the dataset, which means many requests end up applying collapse to millions of documents. This was acceptable in Solr 8, but has become a serious issue after migrating to Solr 9, where the same queries are 2=E2=80=933x slower. We have considered two potential workarounds. First, splitting the index into two =E2=80=94 one for raw documents and one storing pre-collapsed resu= lts. Second, replacing the string sort field (document id) in collapse with a numeric field (hash from the string document id). Both options introduce breaking changes: the index split requires a significant redesign, and changing the collapse sort field type would invalidate all existing cursors stored by clients of the generic tool and require reindexing. Neither is a viable short-term fix. *The goal of this message is to understand what options exist in the current situation without committing to a large engineering effort. * We would also like to raise a broader concern: introducing mandatory LZ4 compression for SortedDocValues term dictionaries in Lucene 9 reduced index size on disk, but introduced a significant performance regression for workloads that rely heavily on string sort fields in collapse queries. Whether this trade-off was intentional, and whether there is a plan to make compression configurable, would be valuable to know. Kind regards, Bartosz On Wed, Jun 24, 2026 at 10:32=E2=80=AFPM Rob Audenaerde <rob.audenaerde@gma= il.com> wrote: > I don't know a direct answer to your questions, but some context of why > you are you running a collapse query on 7m documents could help provide > insight? What are you trying to achieve? Are the results to be paged in a > ui? Is it an analytics workload? > > > > On Wed, Jun 24, 2026, 21:46 Bartosz Fidrysiak <[email protected]> > wrote: > >> We identified a 2=E2=80=933x performance regression in Solr 9.10.1 compa= red to >> Solr 8.11.2 for collapse >> queries that use a string field as a collapse sort field. >> >> >> Test setup >> ---------- >> >> To measure the regression under real production conditions, we configure= d >> both clusters to receive identical traffic simultaneously =E2=80=94 ever= y Solr >> request is sent to both instances at the same time, making the compariso= n >> direct and unbiased. Both clusters have the same number of nodes, >> documents, shards, and shard ranges. The data is sharded by tenant ID, s= o >> each request is served by a single shard with no cross-shard overhead. S= olr >> schema is the same for both clusters. >> >> We tested six query variants covering different combinations of collapse >> sort fields: no collapse, collapse with date sort, date+long sort, >> date+string sort, and string-only sort (see attachments). The results sh= ow >> that queries with a string field in the collapse sort are consistently a= nd >> significantly slower in Solr 9, while queries using only numeric or date >> sort fields show no regression. Notably, the string field used in the >> collapse sort has very high cardinality, and the worst-case queries proc= ess >> millions of documents. >> >> >> [image: image.png] >> [image: image.png] >> [image: image.png] >> >> Root cause >> ---------- >> >> JFR profiling of the worst-case query (sort=3D"modified_date desc, >> document_id asc", ~7M documents) confirmed the root cause. >> [image: image.png] >> >> Lucene 9 changed the internal format for SortedDocValues >> (Lucene90DocValuesProducer). The term dictionary (TermsDict) now stores >> string values in LZ4-compressed blocks. In Lucene 8, the same data was h= eld >> uncompressed in direct memory =E2=80=94 reads were instant. In Lucene 9,= every time >> the collapse logic needs to materialize a string value for comparison or= to >> record a new group winner, it must decompress an LZ4 block. For ~7M >> documents, this decompression is triggered on nearly every document via = the >> following call chain: >> >> SortFieldsCompare >> -> TermOrdValLeafComparator.copy() >> -> lookupOrd() >> -> TermsDict.decompressBlock() >> -> LZ4.decompress() >> >> LZ4 decompression accounts for almost 40% of CPU time in the >> query-serving thread in Solr 9, >> versus near zero in Solr 8. >> >> Similar concerns were raised in >> https://github.com/apache/lucene/issues/11485 >> >> Questions >> --------- >> >> Q1: What are your recommendations for improving the performance of >> collapse queries that use a string field as a sort tiebreaker in Solr 9? >> >> Q2: Is it possible to disable LZ4 compression for SortedDocValues term >> dictionaries =E2=80=94 either via a configuration property or a docValue= sFormat >> option =E2=80=94 or is this something that could be planned for a future= release? >> >> Q3: Would it be feasible to lazily materialize string field values in >> CollapsingQParserPlugin for group winners, so that lookupOrd() is only >> called when a cross-segment comparison is actually needed? This could >> improve performance for queries where most groups contain only one docum= ent. >> >> Kind regards, >> Bartosz >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [email protected] >> For additional commands, e-mail: [email protected] > > --0000000000003644b006550ec5b0--