Solr中使用游标进行深度分页查询以提高效率(适用的场景下)
通常,我们的应用系统,如果要做一次全量数据的读取,大多数时候,采用的方式会是使用分页读取的方式,然而
分页读取的方式,在大数据量的情况下,在solr里面表现并不是特别好,因为它随时可能会发生OOM的异常,在solr里面
通过rows和start参数,非常方便分页读取,但是如果你的start=1000000 rows=10,那么solr里面会将前面100万元数据的索引信息读取在内存里面,这样以来,非常耗内存,所以在solr里面,分页并不适合深度分页。
深度分页在solr里面,更推荐使用游标的方式,游标是无状态的,不会维护索引数据在内存里面,仅仅记录最后一个doc的计算值类似md5,然后每一次读取,都会如此记录最后一个值的mark,下一次通过这个mark便能快速的定位到第二页上,如此往复,便能完成整个数据的读取。而且耗费内存非常少。
假如现在有排好队的10个人等待买饭,而一个房间里面最多一次只能进2个人,那么我们就可以将这个2个人,编号顺序,1和2,他们打完饭后,让2号的人通知,下一组2个人,进来打饭,如此往复
所有人都能吃到饭,这就类似solr中游标的使用。
使用游标的方式读取数据,也有一些约束或者缺点:
(1)查询条件里面必须有cursorMark参数,而且必须不能有start参数
(2)查询的条件里必须按照主键排序(升序或降序),如果没有这个条件,主键重复,那么会造成多个游标的mark值,这样以来下一次请求就不知道如何定位了,而且有可能出现重复读数据的情况
(3)如果一个分页的系统,按照指定页码跳转的功能,这样实现的功能是实现不了的,因为游标一旦读取了,就不能再返回上一次的位置了,这种业务最好使用start+rows搞定。
solrj实现代码例子:
//游标查询
public static void cursorQuery()throws Exception{
//http solr服务
HttpSolrClient sc=new HttpSolrClient("http://localhost:8983/solr/one");
//solr查询封装
SolrQuery sq =new SolrQuery();
sq.setRows(2);//设置游标一次读的数量
sq.set("q", "*:*");//按条件检索
sq.setSort("id", ORDER.asc);//根据主键排序
String cursorMark = CursorMarkParams.CURSOR_MARK_START;//游标初始化
boolean done = false;
while (!done) {
sq.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);//变化游标条件
QueryResponse rsp = sc.query(sq);//执行多次查询读取
String nextCursorMark = rsp.getNextCursorMark();//获取下次游标
//做一些操作数据的事
for(SolrDocument sd:rsp.getResults()){
System.out.println(sd.get("id"));
}
//如果两次游标一样,说明数据拉取完毕,可以结束循环了
if (cursorMark.equals(nextCursorMark)) {
done = true;
}
cursorMark = nextCursorMark;
}
//关闭连接
sc.close();
}
Solr中使用游标进行深度分页查询以提高效率(适用的场景下)的更多相关文章
- elasticserach数据库深度分页查询的原理
深度分页存在的问题 https://segmentfault.com/a/1190000019004316?utm_source=tag-newest 在实际应用中,分页是必不可少的,例如,前端页面展 ...
- 2018.2.28 PHP中使用jQuery+Ajax实现分页查询多功能如何操作
PHP中使用jQuery+Ajax实现分页查询多功能如何操作 1.首先做主页Ajax_pag.php 代码如下 <!DOCTYPE html> <html> <head& ...
- PHP中使用jQuery+Ajax实现分页查询多功能操作
1.首先做主页面Ajax_pag.php 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UT ...
- SpringBoot 整合 Elasticsearch深度分页查询
es 查询共有4种查询类型 QUERY_AND_FETCH: 主节点将查询请求分发到所有的分片中,各个分片按照自己的查询规则即词频文档频率进行打分排序,然后将结果返回给主节点,主节点对所有数据进行汇总 ...
- JPA或Hibernate中使用原生SQL实现分页查询、排序
发生背景:前端展示的数据需要来自A表和D表拼接,A表和D表根据A表的主键进行关联,D表的非主键字段关联C表的主键,根据条件筛选出符合的数据,并且根据A表的主键关联B表的主键(多主键)的条件,过滤A表中 ...
- solr研磨之游标分页
普通分页 当需要深度分页的时候,比如查询第10000页数据,每页显示10条,意味着需要提取前10000 x 10 页的数据,并将这100000条数据缓存在内存中,然后在内存中进行排序.最后返回最后10 ...
- elasticsearch深度分页问题
elasticsearch专栏:https://www.cnblogs.com/hello-shf/category/1550315.html 一.深度分页方式from + size es 默认采用的 ...
- 【java】分页查询实体类
package com.dmsd.itoo.tool.pageModel; import java.io.Serializable; import java.util.HashMap; import ...
- Oracle、MySql、SQLServer 数据分页查询
最近简单的对oracle,mysql,sqlserver2005的数据分页查询作了研究,把各自的查询的语句贴出来供大家学习..... (一). mysql的分页查询 mysql的分页查询是最简单的,借 ...
随机推荐
- java zip 压缩文件
zip压缩:ZipOutputStream.ZipFile.ZipInputStream 三个类的作用 一段 java zip 压缩的代码: File dir = new File("C ...
- LOJ 3055 「HNOI2019」JOJO—— kmp自动机+主席树
题目:https://loj.ac/problem/3055 先写了暴力.本来想的是 n<=300 的那个在树上暴力维护好整个字符串, x=1 的那个用主席树维护好字符串和 nxt 数组.但 x ...
- golang 自定义json解析
在实际开发中,经常会遇到需要定制json编解码的情况. 比如,按照指定的格式输出json字符串, 又比如,根据条件决定是否在最后的json字符串中显示或者不显示某些字段. 如果希望自己定义对象的编码和 ...
- 《Windows核心编程》第3章——深入理解handle
本文借助windbg来理解程序中的函数如何使用handle对句柄表进行查询的.所以先要开启Win7下Windbg的内和调试功能. 解决win7下内核调试的问题 win7下debug默认无法进行内核调试 ...
- CentOS6.4 添加php-fpm系统服务
简介: php-fpm安装完成后默认不会注册为系统服务,所以需要手工添加系统服务脚本.在/etc/init.d目录下新建php-fpm文件,并更改权限其即可. 1.检测/usr/local/php/v ...
- jQuery同一标签多个相同事件 return语句 表单提交实例
如form表单的submit,a标签都自带一个鼠标单击事件,其实我们还可以额外填加单击事件 如:$(':submit').click(); 则自定义的单击事件先执行,然后才是标签自带的单击事件(c ...
- responsiveslides 插件(图片轮播插件)
参数详解: $(".rslides").responsiveSlides({ auto: true, // Boolean: 设置是否自动播放, true or false spe ...
- C# 中HttpClient的使用中同步异步问题
项目中遇到了这样的问题: 第一次 :HttpResponseMessage response = await httpClient.PostAsync(url, null);发送了一个post异步请求 ...
- List<T>Distinct 过滤
public class TestDuplicateDefine : IEqualityComparer<student> { public bool Equals(student x, ...
- 记录一次OOM分析过程
工具: jstat jmap jhat 1.jstat查看gc情况 S0C.S1C.S0U.S1U:Survivor 0/1区容量(Capacity)和使用量(Used) EC.EU:Eden区容量和 ...