【问题标题】:Solr poor performance on date range querySolr 在日期范围查询上表现不佳
【发布时间】:2018-06-21 08:50:11
【问题描述】:

我目前正在努力在 Solr 4.10 (CDH 5.14) 中通过日期范围查询的 NRT 索引在大约 1800 万个文档核心上获得不错的性能。 我尝试了多种策略,但似乎一切都失败了。

每个文档都有多个版本(10 到 100),在不同的非重叠时段(开始时间/结束时间)有效。

查询模式如下:查询 referenceNumber(或其他条件),但仅返回在 referenceDate(日期精度)有效的文档。 75% 的查询选择过去 30 天内的参考日期。 如果我们在不使用 referenceDate 的情况下进行查询,我们会获得非常好的性能,但使用额外的 referenceDate 过滤器会减慢 100 倍,即使将其强制作为后过滤器也是如此。

这里有一些性能测试来自执行 http 查询并计算 100 个不同 referenceNumber 的 QTime 的 python 脚本。

+----+-------------------------------------+----------------------+--------------------------+
| ID | Query                               | Results              | Comment                  |
+----+-------------------------------------+----------------------+--------------------------+
| 1  | q=referenceNumber:{referenceNumber} | 100 calls in <10ms   | Performance OK           |
+----+-------------------------------------+----------------------+--------------------------+
| 2  | q=referenceNumber:{referenceNumber} | 99 calls in <10ms    | 1 call to warm up        |
|    | &fq=startDate:[* to NOW/DAY]        | 1 call   in >=1000ms | the cache then all       |
|    | AND    endDate:[NOW/DAY to *]       |                      | queries hit the filter   |
|    |                                     |                      | cache. Problem: as       |
|    |                                     |                      | soon as new documents    |
|    |                                     |                      | come in, they invalidate |
|    |                                     |                      | the cache.               |
+----+-------------------------------------+----------------------+--------------------------+
| 3  | q=referenceNumber:{referenceNumber} | 99 calls in >=500ms  | The average of           |
|    | &fq={!cache=false cost=200}         | 1  call  in >=1000ms | calls is 734.5ms.        |
|    | startDate:[* to NOW/DAY]            |                      |                          |
|    | AND    endDate:[NOW/DAY to *]       |                      |                          |
+----+-------------------------------------+----------------------+--------------------------+

额外的日期范围过滤器查询怎么可能造成 100 倍的减速?从这个博客中,我预计 daterange 查询的性能与没有附加过滤器的性能相似:http://yonik.com/advanced-filter-caching-in-solr/

或者是唯一的选择是更改 softCommit/hardCommit 延迟,在过去 30 天内创建 30 个预热 fq 并容忍 25% 的查询性能不佳?

编辑 1:感谢您的回答,不幸的是,使用整数而不是 tdate 似乎并没有提供任何性能提升。它只能利用缓存,例如上面的查询 ID 2。这意味着我们需要一个 30+ fq 的热身策略。

+----+-------------------------------------+----------------------+--------------------------+
| ID | Query                               | Results              | Comment                  |
+----+-------------------------------------+----------------------+--------------------------+
| 4  | fq={!cache=false}                   | 35 calls in <10ms    |                          |
|    | referenceNumber:{referenceNumber}   | 65 calls in >10ms    |                          |
+----+-------------------------------------+----------------------+--------------------------+
| 5  | fq={!cache=false}                   | 9 calls in >100ms    |                          |
|    | referenceNumber:{referenceNumber}   | 6 calls in >500ms    |                          |
|    | AND versionNumber:[2 TO *]          | 85 calls in >1000ms  |                          |
+----+-------------------------------------+----------------------+--------------------------+

编辑 2:似乎将我的 referenceNumber 从 fq 传递到 q 并设置不同的成本可以改善查询时间(不完美,但更好)。奇怪的是 cost >= 100 应该作为 postFilter 执行,但是将 cost 从 20 设置为 200 似乎根本不会影响性能。有谁知道如何查看 fq 参数是否作为后过滤器执行?

+----+-------------------------------------+----------------------+--------------------------+
| 6  | fq={!cache=false cost=0}            | 89 calls in >100ms   |                          |
|    | referenceNumber:{referenceNumber}   | 11 calls in >500ms   |                          |
|    | &fq={!cache=false cost=200}         |                      |                          |
|    | startDate:[* TO NOW] AND            |                      |                          |
|    | endDate:[NOW TO *]                  |                      |                          |
+----+-------------------------------------+----------------------+--------------------------+
| 7  | fq={!cache=false cost=0}            | 36 calls in >100ms   |                          |
|    | referenceNumber:{referenceNumber}   | 64 calls in >500ms   |                          |
|    | &fq={!cache=false cost=20}          |                      |                          |
|    | startDate:[* TO NOW] AND            |                      |                          |
|    | endDate:[NOW TO *]                  |                      |                          |
+----+-------------------------------------+----------------------+--------------------------+

【问题讨论】:

  • 我也有同样的问题。有人知道答案吗
  • 该领域的precisionStep是多少?
  • .. 升级到新版本的 Solr 是一种选择吗?稍后介绍的 DateRangeField,它使用空间特征来提供适当的范围支持。
  • startDate/endDate 的precisionStep 为6,versionNumber 的precisionStep 为0。不,无法更新solr,因为它是CDH 5.14 的一部分。 Solr 7 将在今年到期的下一版本 CDH 中提供。
  • 我猜versionNumber 的范围足够小,以至于更改precisionStep 无论如何都不会做太多事情。较大的precisionStep 可以帮助日期减少略微生成的令牌数量,但6 或8 通常是好的值。 10 将类似于范围搜索的最接近秒的分辨率。如果您只是按天搜索,更大的precisionStep 可能会很有用,但如果不使用您的数据集和查询配置文件进行测试,就很难说。

标签: solr solrcloud


【解决方案1】:

您好,我为您提供了另一个解决方案,在对 solr 执行相同的查询后,它会提供良好的性能。

My Suggestion is store date in int format, please find below example.

 Your Start Date : 2017-03-01
 Your END Date : 2029-03-01

**Suggested format in int format. 
 Start Date : 20170301
 END Date : 20290301**

当您尝试使用 int 数字而不是日期触发相同的查询时,它会按预期更快地运行。

 So your query will be.
q=referenceNumber:{referenceNumber}
&fq=startNewDate:[* to YYMMDD]
AND    endNewDate:[YYMMDD to *] 

希望对你有所帮助..

【讨论】:

  • 感谢您的提议。我更新了描述以反映您的解决方案,但与日期相比,它似乎没有提供任何性能:[* TO NOW/DAY] 解决方案。
  • TrieDate 在内部被索引为 long,因此这与使用常规日期字段相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
  • 2019-08-16
  • 2014-12-17
相关资源
最近更新 更多