当前位置:网站首页>使用StreamAPI 断言组合,结合本地缓存做模糊查询(比mysql效率提升近1000倍)
使用StreamAPI 断言组合,结合本地缓存做模糊查询(比mysql效率提升近1000倍)
2022-06-21 20:16:00 【每天都要加油呀!】
使用StreamAPI 断言结合本地缓存做模糊查询(比mysql效率提升近1000倍)
最近手上有个需求,需要做模糊查询,第一时间想到的是mysql分页模糊查询,但是甲方的需求是模糊查询所有的数据,且这个模糊查询也不好通过添加索引进行优化
拿到这个需求后,我往大概2w条数据的数据库中全表模糊查询了一下,耗时大概在10s左右:

然后我想其实我的数据量并不大,表中的数据很难也几乎不可能突破十万条数据,如果我直接存在JVM缓存中是不是快一些
说干就干,这里我使用Stream中断言组合的方式进行模糊查询,不熟悉的小伙伴可以看附录中的小例子
这里我根据模糊查询的字段进行断言组合:
@Override
public List<T> likeQuery(Map<String, Object> queryMap) {
// 这里需要先组合断言,因为是与运算,所以初始化一个成功的断言
Predicate<Book> p = Objects::nonNull;
for (Entry<String, Object> entry : queryMap.entrySet()) {
String k = entry.getKey();
String v = String.valueOf(entry.getValue());
Predicate<Book> p2 = null;
if (k.equalsIgnoreCase("bookName")) {
p2 = book -> book.matchName(v);
} else if (k.equalsIgnoreCase("author")) {
p2 = book -> book.matchAuthor(v);
} else if (k.equalsIgnoreCase("publishArea")) {
p2 = book -> book.matchPublishArea(v);
}
// 断言组合
if (p2 != null){
p = p.and(p2);
}
}
// 我是自己用List做的缓存,所有这里通过this获取
return this.stream()
.filter(p)
.collect(Collectors.toList());
}
然后在实体类中写上比较的逻辑:
@Override
public boolean matchName(String str) {
if(this.bookName == null) return false;
return this.bookName.contains(str);
}
接下来就是看效果的时候了,实测两万条数据做模糊查询不会超过100ms,一般会更低,且这里还包括http请求的时间

通过
AB测对该接口做一下压测,共设置1000个线程,做十万次请求并记录时间
十万个请求仅耗时31秒

查看JVM堆空间占用情况
发现缓存2万条数据,堆空间占用也在合理范围,且GC后占用内存会大大降低

线程数也在合理范围
在前端模糊查询,非常丝滑,毫无卡顿

小结:
这里建议不要轻易使用并行流对性能进行提升,因为并且流在处理过程中有许多不可控的风险,例如如果使用线程不安全的集合类进行并行流操作时,极有可能产生线程安全问题
笔者建议使用fork/join框架手动拆分任务,保证线程安全
附录,Stream断言组合模糊查询例子
Predicate:<T>断言型接口; 输入一个对象,返回一个Boolean值,需要实现的抽象函数为boolean test(T t)
例如:
/** * 4.Predicate<T>:断言型接口 */
@Test
public void test04(){
List<String> list= Arrays.asList("Hello","我乃梁奉先是也","Lambda","www","ok");
//过滤长度大于三的字符串
System.out.println(filterStr(list,(str)->str.length()>3));
}
//需求,将满足条件的字符串添加到集合中
private List<String> filterStr(List<String> list, Predicate<String> predicate) {
List<String> strList = new ArrayList<>();
for (String str : list) {
if (predicate.test(str)) {
strList.add(str);
}
}
return strList;
}
断言组合(谓词组合),与或非
public class PredicateFunction {
//抽取公共代码
static List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> p){
List<Apple> result = new ArrayList<>();
inventory.forEach(apple -> {
if(p.test(apple)){
result.add(apple);
}
});
return result;
}
public static void main(String[] args) {
String[] colors = {
"green","yellow","blue"};
Random r = new Random();
List<Apple> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(new Apple(colors[r.nextInt(colors.length)],r.nextInt(200)));
}
System.out.println(filterApples(list,Apple::isGreenApple));
System.out.println(filterApples(list,Apple::isHealthyApple));
//组合两个条件
Predicate<Apple> p1 = Apple::isGreenApple;
Predicate<Apple> p2 = Apple::isHealthyApple;
//或运算
System.out.println(filterApples(list,p1.or(p2)));
//and运算
System.out.println(filterApples(list,p1.and(p2)));
}
}
@Data
@AllArgsConstructor
class Apple{
private String color;
private int weight;
public static boolean isGreenApple(Apple apple){
return "green".equalsIgnoreCase(apple.getColor());
}
public static boolean isHealthyApple(Apple apple){
return apple.getWeight() > 150;
}
}
边栏推荐
- phpmailer 通过smtp发送邮件,相同发送内容有的成功有的失败
- Background and specificity of Worthington elastase
- Jerry's problem of playing songs after opening four channel EQ [chapter]
- What is EGFP, green fluorescent protein
- Improve four performance! D-wave releases next generation quantum annealing prototype
- 提升方法(上)AdaBoost
- Tkinter drawing component (29) -- Radio Group Control
- 超越同龄人,普通女生下班后如何自学自媒体视频剪辑?
- 杰理之做蓝牙发射时,将立体声修改成单声道差分输出时,接收端出现卡音【篇】
- Abbkine细胞周期染色试剂盒特色和实验建议
猜你喜欢

你真的了解二叉树吗?(上篇)

GAMES101作业7-多线程提速实现步骤详解

广东疾控提醒:暑期将至,返粤大学生这样安全“归巢”

杰理之配对成对耳后,想保持两个耳机都输出立体声【篇】

大型语言模型教会智能体进化,OpenAI这项研究揭示了二者的互补关系

Six interesting web page effects that can be used

Introduction to security encryption

赋·新生,链·未来!城链科技产业赋能创新发展大会隆重举行

杰理之开启四声道打开 EQ 后播歌卡顿问题【篇】

Large language models teach agents to evolve. Openai reveals the complementary relationship between the two
随机推荐
M3608 boost IC chip high efficiency 2.6a boost dc/dc converter
Revenue and profit "ebb and flow", water drops turn in pain
Excuse me, which website is better for college students to check literature?
phpmailer 通过smtp发送邮件,相同发送内容有的成功有的失败
Jerry's near end tone change problem of opening four channel call [chapter]
杰理之做蓝牙发射的时候,回链没有声音解决方法【篇】
C#的DataGridView中字体大小
杰理之配对成对耳后,想保持两个耳机都输出立体声【篇】
7.目标检测
面了十多家实习岗位失败的实习面试经历总结
Thoroughly understand the foundation of MySQL: the difference between B tree and b+ tree
Summary of internship interview experience of more than ten failed internship positions
Spark 离线开发框架设计与实现
AWS CloudWatch
Intelij idea efficient skills (II)
tkinter绘制组件(29)——单选组控件
How to write a proposal for an English paper?
prototype扩展:实现对象继承
Worthington deoxyribonuclease I solution
Yx2811 landscape installation driver IC