赞
踩
Elasticsearch(ES)中进行分页查询时,最佳实践取决于具体的使用场景和需求。
以下是对每种分页方法的简要分析以及它们适用的情况:
from
参数指定跳过多少条记录,size
参数指定每次返回多少条记录。from
值增大,查询效率会显著降低,尤其是在深度分页的情况下(例如,查询很多页之后的数据),因为ES需要遍历所有之前的结果才能找到指定偏移的结果集,这对分布式系统来说成本非常高。from+size
在深度分页时的性能瓶颈。_score
或用户定义的排序字段来进行连续查询,避免了大规模跳跃式分页的问题。相比from+size
,它在深度分页时性能更优,同时能够更好地处理实时变化的数据。search_after
模式。package org.example; import org.apache.http.HttpHost; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchScrollRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import java.io.IOException; import java.util.concurrent.TimeUnit; public class ESScrollMain { private static final String indexName = "kibana_sample_data_logs"; public static void main(String[] args) throws IOException { System.out.println("Hello and welcome!"); RestClientBuilder builder = RestClient.builder(new HttpHost("10.x.x.x", 9200, "http")); RestHighLevelClient client = new RestHighLevelClient(builder); SearchRequest searchRequest = new SearchRequest(indexName); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // hit 返回值(bool 查询返回条数) // searchSourceBuilder.size(0); // searchSourceBuilder.from(0); searchSourceBuilder.trackTotalHits(true); // 超时时间60s MatchAllQueryBuilder search = QueryBuilders.matchAllQuery(); searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); searchSourceBuilder.size(2000); searchSourceBuilder.query(search); long scrollTime = 30L; searchRequest.source(searchSourceBuilder); searchRequest.scroll(TimeValue.timeValueSeconds(scrollTime)); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); String scrollId = searchResponse.getScrollId(); SearchHit[] hits = searchResponse.getHits().getHits(); int count = 0; int batch = 1; System.out.println("初始结果条数:" + count); count += hits.length; System.out.println("滚动第" + batch + "批结果总条数:" + count); while (hits != null && hits.length > 0) { batch++; SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId); scrollRequest.scroll(TimeValue.timeValueSeconds(scrollTime)); searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT); scrollId = searchResponse.getScrollId(); hits = searchResponse.getHits().getHits(); count += hits.length; System.out.println("滚动第" + batch + "批结果总条数:" + count); } System.out.println("结束,总计:"+searchResponse.getHits().getTotalHits()); } }
from+size
足够。search_after
。此外,针对大型分页查询的性能优化还可以包括:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。