【发布时间】:2016-07-07 07:49:10
【问题描述】:
我在 ES 索引中有父子关系。就文档数量而言,父母(200M 文档)和 80% 孩子(1B 文档)的文档数量分布约为 20%。 ES 集群有 5 个节点,每个节点有 20GB RAM 和 4 个 CPU 内核。 ES 版本是 1.5.2。我们每个索引使用 5 个分片和 0 个复制。
当我使用has_child 查询它时,处理速度非常慢 - 170 秒。然而,当我只是跑过父母时,不到一秒钟。
此查询需要很长时间才能返回并导致应用程序超时。我真的很关心聚合和时间范围过滤器。
我相信正在发生的事情是查询首先在每个孩子身上运行以进行过滤。实际上,我只希望它先运行父母并检查是否有单个文档,然后对孩子使用过滤器。
设置
_parent 是一个看起来像这样的操作
{
"a": "m_field",
"b": "b_field",
"c": "c_field",
"d": "d_field"
}
_child 是该操作发生时的时间戳
{
"date": "2016-07-07T11:11:11Z"
}
这些通常存储在时间序列索引中。索引按月分片。一个索引通常在磁盘上占用大约 70GB 的总大小。我们选择通过别名运行它,该别名结合了所有或部分最新索引。
查询
当我查询时,我在 _parent 文档上执行 query_string 以搜索 keyword 和子级上的 Range 过滤器,使用 has_child 查询。
如下所示。
{
"size": 0,
"aggs": {
"base_aggs": {
"cardinality": {
"field": "a"
}
}
},
"query": {
"bool": {
"must": [
{
"filtered": {
"query": {
"query_string": {
"query": "*",
"fields": [
"a",
"b",
"c",
"d",
"e"
],
"default_operator": "and",
"allow_leading_wildcard": true,
"lowercase_expanded_terms": true
}
},
"filter": {
"has_child": {
"type": "evt",
"min_children": 1,
"max_children": 1,
"filter": {
"range": {
"date": {
"lte": "2016-07-06T23:59:59.000",
"gte": "2016-06-07T00:00:00.000"
}
}
}
}
}
}
}
],
"must_not": [
{
"term": {
"b": {
"value": ""
}
}
},
{
"term": {
"b": {
"value": "__"
}
}
}
]
}
}
}
所以查询应该在我的query_string 上与条目“*”匹配,并且有两个提供的日期之间的孩子。因为我只关心聚合我不返回任何文档,我只需要匹配单个子文档。
问题
如何提高查询速度?
【问题讨论】:
标签: elasticsearch