要不要也来分享分享一下啊

range keyword 与日期 查询顺序性能

匿名 | 发布于2019年12月09日 | 阅读数:2367

数据总量大概在 1 千万,id 自己生成,数据类型为 keyword ,字符串长度为 11 ,另有displaytime 使用日期格式存储,存储内容为毫秒时间戳;查询方式如下:
{
"query": {
"bool": {
"filter": [
{
"range": {
"displaytime": {
"from": 1565697740000,
"to": 1575697740000
}
}
},
{
"range": {
"id": {
"from": null,
"to": "xxxxxxxxxxx"
}
}
}
]
}
}
}
耗时大概在 500 ms 左右;
 
但是在只用时间进行过滤查询耗时只有 10 ms 左右(命中数据 20 万):
{
"query": {
"bool": {
"filter": [
{
"range": {
"displaytime": {
"from": 1565697740000,
"to": 1575697740000
}
}
}
]
}
}
}
只使用 id 进行查询耗时 500ms 左右(命中 900 万数据):
{
"query": {
"bool": {
"filter": [
{
"range": {
"aid": {
"from": null,
"to": "xxxxxxxxxxx"
}
}
}
]
}
}
}
交换第一次查询的顺序并没有效果,官方文档也说明具体查询内部会进行优化;结果上来看两次过滤查询是并行执行,并没有在缩小范围的基础上再进行第二次过滤,有什么解决办法么?
已邀请:

Ombres

赞同来自:

你的场景下keyword类型的id字段并不适合做范围查询,具体原因是因为这种类型使用的是SortedSetDocValues,这种结构会创建一个ordMap来存储每个term的ord序号,而你的数据是id,可以想象每个都不一样,这样就会导致创建的ordMap特别大,时间消耗主要就在构建这个ordMap了。
时间戳就不一样了,它的底层是数值类型,使用的是NumericDocValues,并不会生成ordMap。

可以通过profile:true查看一下执行计划。
 
 

要回复问题请先登录注册