当前位置:网站首页>使用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;
}
}
边栏推荐
- Jerry's acquisition of current audio file (long) file name and current (long) folder name [chapter]
- Advanced packaging, the beginning of a big cycle -- a symposium on semiconductor equipment
- Wechat applet JS converts numbers into letters
- From casual to boring to sick
- #15迭代器
- 洛谷P5440 【XR-2】奇迹 题解
- Large language models teach agents to evolve. Openai reveals the complementary relationship between the two
- solidity实现智能合约教程(4)-ERC1155合约
- Huawei Hongmeng development lesson 3
- Enzo高灵敏度检测——Arg8-Vasopressin ELISA kit
猜你喜欢

Does the whole house smart home brand "zhiting technology" have an experience center?

电子招标采购商城系统:优化传统采购业务,提速企业数字化升级

Do280openshift command and troubleshooting -- accessing resources and resource types
![When Jerry made Bluetooth transmission, when he modified stereo to mono differential output, there was a jam sound at the receiving end [chapter]](/img/ef/35a74fe3b1a8035afb6c50e6880860.png)
When Jerry made Bluetooth transmission, when he modified stereo to mono differential output, there was a jam sound at the receiving end [chapter]

Fs9935 high efficiency constant current limiting WLED drive IC

阿里云容器服务负责人易立:云原生如何解企业降本提效难题?

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

Ln2220 2A overcurrent 5v1a High Efficiency Boost IC chip dc/dc voltage regulator

C language array and pointer exercises (original question + analysis + original code)

Thoroughly understand the foundation of MySQL: the difference between B tree and b+ tree
随机推荐
Specificity and application of Worthington Papain
From casual to boring to sick
prototype扩展:实现对象继承
How to search foreign literature efficiently?
How to use the free and easy-to-use reference management software Zotero? Can I support both Chinese and English
LeetCode508-出现次数最多的子树元素和-深搜
JS异步的执行顺序是什么
JS object operation (much simpler than C object)
杰理之获取当前音频文件(长)文件名和当前(长)文件夹名【篇】
Tutorial on the implementation of smart contracts by solidity (4) -erc1155 contracts
Eureka console accesses the info endpoint exposed by the microservice
3D octave view
Worthington collagenase raw material
Time modification method for search device of Jerry's Bluetooth transmitter [chapter]
Fu · new life, chain · future! The conference on enabling innovation and development of urban chain technology industry was held grandly
Do you really know binary tree? (Part I)
Is the security of the securities account given by digging money safe? Can I open an account?
自制C#编译器
大不列颠泰迪熊加入PUBG 手游
phpmailer 通过smtp发送邮件,相同发送内容有的成功有的失败