一、使用场景介绍

elasticsearch除了普通的全文检索之外,在很多的业务场景中都有使用,各个业务模块根据自己业务特色设置查询条件,通过elasticsearch执行并返回所有命中的记录的id;如果命中的记录数达到数万级别的话,查询性能会有明显的下降,尤其是命中超大型的document的时候;

获取记录的id目前可以使用的有三种方式;

通过_source:["id"]

设置_source:false,通过es返回的元数据_id分离出device的id;

使用store=true来单独的存储device id,查询的时候使用stored_fields= ['id'];

二、store映射参数

默认情况下,字段值会被索引以使其可搜索,但不会存储它们。这意味着可以查询该字段,但不能检索原始字段值。

通常这并不重要。该字段值已经是_source字段的一部分,该字段是默认存储的。如果您只想检索单个字段或几个字段的值,而不是整个_source,那么可以通过_source过滤来实现。

在某些情况下,存储字段是有意义的。例如,如果你有一个文档,一个标题,一个日期,和一个非常大的内容字段,你可能想只检索标题和日期,而不必从一个大的_source字段提取这些字段:

设置对应字段的store参数为true,并创建mapping;

PUT my_store_test
{
"mappings": {
"_doc": {
"properties": {
"title": {
"type": "text",
"store": true
},
"date": {
"type": "date",
"store": true
},
"content": {
"type": "text"
}
}
}
}
} {
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "my_store_test"
}

put一个document进行索引

PUT my_store_test/_doc/1
{
"title": "Some short title",
"date": "2015-01-01",
"content": "A very long content field..."
} {
"_index" : "my_store_test",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}

通过在查询语句中设置stored_fields来筛选要返回的字段,elasticsearch返回的fields字段包含对应的字段值;

GET my_store_test/_search
{
"stored_fields": [ "title", "date" ]
} {
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_store_test",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"fields" : {
"date" : [
"2015-01-01T00:00:00.000Z"
],
"title" : [
"Some short title"
]
}
}
]
}
}

三、测试情况

我们测试使用my_store_index,里边包含50W的document,还有一些特别大的document;

我们fetch_ids_query进行测试

默认情况下通过elasticsearch查询返回的_source字段获取记录的id字段;

通过take_from__id控制从elasticsearch查询返回的元数据_id解析出记录id;

通过task_stored_fields控制从elasticsearch查询返回的fields获取记录的id;

from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search, Q
import time def fetch_ids_query(client, take_from__id = False, task_stored_fields = False):
start = time.time()
s = Search(using=client, index="my_store_index")
s = s.params(http_auth=["test", "test"], request_timeout=50);
q = Q('bool',
must_not=[Q('match_phrase_prefix', name='us')]
)
s = s.query(q) s = s.source(False) if take_from__id else s.source(['id'])
if task_stored_fields:
s = s.extra(stored_fields= ['id'])
s = s.source(False) s = s[0:40000]
response = s.execute() print(f'hit total {response.hits.total}')
print(f'fetch total {len(response.hits.hits)}') ids = []
if take_from__id:
for hit in response.hits.hits:
id = hit['_id'][37:]
ids.append(id)
elif task_stored_fields:
for hit in response.hits.hits:
id = hit.fields['id'][0]
ids.append(id)
else:
for hit in response.hits.hits:
id = hit._source['id']
ids.append(id) end = time.time()
print(f"all execute time {end - start}s") client = Elasticsearch(hosts=['http://127.0.0.1:9200'], http_auth=["test", "test"]) print('fetch id from source')
fetch_ids_query(client);
print()
print('fetch id from _id and set source = false')
fetch_ids_query(client, True);
print()
print('fetch id from stored id and set source = false')
fetch_ids_query(client, False, True);

四、测试结果

经测试在命中484970,fetch 40000条记录的前提下,后两种方式的执行时间更短,但是通过元数据解析_id会更加友好,不仅节省存储空间,而且查询的时候避免了内存和CPU的震荡;

fetch id from source
hit total 484970
fetch total 40000
all execute time 28.691869497299194s fetch id from _id and set source = false
hit total 484970
fetch total 40000
all execute time 11.315539121627808s fetch id from stored id and set source = false
hit total 484970
fetch total 40000
all execute time 13.930094957351685s

elasticsearch查询之三种fetch id方式性能测试的更多相关文章

  1. 05.Python网络爬虫之三种数据解析方式

    引入 回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指 ...

  2. Python爬虫之三种数据解析方式

    一.引入 二.回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需 ...

  3. 05,Python网络爬虫之三种数据解析方式

    回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据 ...

  4. 《Python网络爬虫之三种数据解析方式》

    引入 回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指 ...

  5. Katalon Studio入门学习之三种获取元素方式

    Katalon Studio中元素属性定位有三种方式,分别是XPath.Attributes(元素).CSS(样式),KS的界面展示如右图 打开网站,按F12或进入浏览器设置->更多工具-> ...

  6. Python网络爬虫之三种数据解析方式 (xpath, 正则, bs4)

    引入 回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指 ...

  7. Python网络爬虫之三种数据解析方式

    1. 正则解析 正则例题 import re # string1 = """<div>静夜思 # 窗前明月光 # 疑是地上霜 # 举头望明月 # 低头思故乡 ...

  8. 【原】iOS学习之三种拨打电话方式的比较

    拨打电话小编从网上找到三种,在这里做一些总结和比较 1.基本使用 NSString *str = [[NSMutableString alloc] initWithFormat:@"tel: ...

  9. 一种更高查询性能的列存储方式MaxMinT 第一部分

    简介本文描述了一种列存储方式和对应的查询方法,这种存储方式具有更好的查询性能和更小的存储空间. And查询 本文先用直观的图形方式展示and查询时的方式,这也是算法要解决的问题核心.通常在OLAP数据 ...

随机推荐

  1. 基于LNMP环境的Zabbix监控安装

    一.准备LNMP环境 1.使用putty或类似的SSH工具登陆VPS或服务器: 登陆后运行:screen -S lnmp 如果提示screen: command not found 命令不存在可以执行 ...

  2. 第10组 Alpha冲刺 (2/6)

    1.1基本情况 ·队名:今晚不睡觉 ·组长博客:https://www.cnblogs.com/cpandbb/ ·作业博客:https://edu.cnblogs.com/campus/fzu/FZ ...

  3. HDOJ1573X问题

    https://acm.hdu.edu.cn/showproblem.php?pid=1573 n组线性同余方程求解,最后求出多少解.而最终的解的周期为最小公倍数,范围内的,需要这样算.如果最小超过, ...

  4. FastDFS文件的上传和下载

    一.FastDFS概述: FastDFS是一个开源的轻量级分布式文件系统,他对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.下载)等,解决了大容量存储和负载均衡的问题,高度追求高性能 ...

  5. JavaScript创建和获取时间的方法

    一.获取时间常用方法 1.创建时间对象 var time=new Date() //创建当前的时间信息对象 var time1=new Date(2022,1,1,10,25,30) //创建2022 ...

  6. mate10碎屏机当成小电脑使用尝试

    1.屏碎了修起来300-400,自己动手至少也要260以上买个屏幕钱. 手机图案锁屏也不知道密码,给我手机的亲戚忘了.当年手机被车压弯了. 对着恢复教程,盲屏幕猜着按还原了. 2.之后一路从8代系统更 ...

  7. HttpServletResponse接口详解

    在 Servlet API 中,定义了一个 HttpServletResponse 接口,它继承自 ServletResponse 接口.HttpServletResponse 对象专门用来封装 HT ...

  8. Python 安装MySQL 错误处理

    正常情况下如果使用python 连接数据库需要安装 python-MySQL 类库 #pip install python-MySQL 等待安装完成即可 使用时 import MySQLdb ==== ...

  9. nginx模块lnmp架构

    目录 一:关于lnmp架构 二:目录索引模块 1.目录索引模块内容 1.开启目录索引(创建模块文件) 2.测试 3.重启nginx 4.配置域名解析DNS 5.网址测试 二:目录索引(格式化文件大小) ...

  10. 学习MyBatis必知必会(2)~MyBatis基本介绍和MyBatis基本使用

    一.MyBatis框架基本介绍: 1.认识 MyBatis: MyBatis 是支持普通 SQL 查询,存储过程和高级映射的持久层框架,严格上说应该是一个 SQL 映射框架. 其前身是 iBatis, ...