沙师弟,师父的充电器掉了

Elastic对类似枚举数据的搜索性能优化

Elasticsearch | 作者 hufuman | 发布于2018年01月02日 | 阅读数:12570

我们有以下的Query,多次查询发现tag_id、status、isaudited几个字段都可能是性能瓶颈
求问有什么可以优化的手段吗?
 
ES:5.3.2
DocCount:1,2434,9270
CPU:32*6
Mem: 128*6
查询、排序的字段,均为long类型
profile结果内容太多,我放在附件里了 

Query:
{
    "profile": true,
    "size": 20, 
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "tag_id": 84220
                    }
                }, 
                {
                    "term": {
                        "status": 6
                    }
                }, 
                {
                    "term": {
                        "is_audited": 0
                    }
                }
            ]
        }
    }, 
    "from": 0, 
    "_source": [
        "PublishTime"
    ], 
    "sort": [
        {
            "Weighting": {
                "order": "desc"
            }
        }, 
        {
            "CustomRank": {
                "order": "desc"
            }
        }, 
        {
            "PublishTime": {
                "order": "desc"
            }
        }
    ]
}
 
 
已邀请:

kennywu76 - Wood

赞同来自: hufuman laoyang360 napoleonu pqy Xiaoming ghsy158 wkdx hsd249022043更多 »

这两天刚好和一个朋友在讨论这个问题,初步判断是因为5.0以后对于数值型字段采用了block k-d tree索引结构,导致status一类不同值不多,每个值对应的文档比较多的情况下,查询会比较缓慢。 
 
改用keyword字段来索引就快了, 深层次原因还在看代码探寻。

huganle

赞同来自: hufuman

es5对数字类型的索引存储方式是通过kd-tree来实现的,这个是为了优化范围查询,但是如果要精确匹配的话就蛋疼了。如果在status这种只有有限个值的字段上一般不会涉及到范围查询,可以直接改成keyword类型,精确匹配会快很多。可以看看下面两篇文章:
https://www.elastic.co/blog/be ... earch
https://www.elastic.co/blog/el ... order

kennywu76 - Wood

赞同来自:

今天找时间做了各种测试,同时参考了好几篇技术文档, 基本可以断定这个问题实际上由2个因素共同影响:
其一: 5.0以后number类型改为block k-d tree索引,对于低cardinality的number类型字段做conjuntion性能差。
其二: Build cache的逻辑。  
 
等我有空的时候写篇博客详细解释一下。

spoofer

赞同来自:

问一下,如果mapping 定义为keyword ,但是入库时的json字段的值为int,这样es会索引为keyword还是int?

要回复问题请先登录注册