自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

兩組數(shù)據(jù)量相對大時,如何高效進行比對

大數(shù)據(jù) 新聞
這三種方案,兩層循環(huán)效率是最低,而且隨著數(shù)據(jù)量增大會有OOM的風險。

01 前言

前陣子項目因業(yè)務(wù)需要,要對接兄弟部門的用戶數(shù)據(jù),因為兄弟部門并不提供增量用戶數(shù)據(jù)接口,每次只能從兄弟部門那邊同步全量用戶數(shù)據(jù)。全量的用戶數(shù)據(jù)大概有幾萬條。因為是全量數(shù)據(jù),因此我們這邊要做數(shù)據(jù)比對( 注:  用戶username是唯一),如果同步過來的數(shù)據(jù),我們這邊沒有,就要做插入操作,如果我們這邊已經(jīng)有,就要做更新操作。本文就來聊聊當數(shù)據(jù)量相對大時,如何進行對比

02 比對邏輯

因用戶username是唯一的,因此我們可以利用用戶username來進行比對匹配

03 比對實現(xiàn)

1.方案一:兩層嵌套循環(huán)比對

即:將接口的全量數(shù)據(jù)和我們數(shù)據(jù)庫的全量數(shù)據(jù)進行循環(huán)比對

示例

@Override
public void compareAndSave(List<User> users, List<MockUser> mockUsers) {
List<User> addUsers = new ArrayList<>();
List<User> updateUsers = new ArrayList<>();
for (MockUser mockUser : mockUsers) {
for (User user : users) {
if(mockUser.getUsername().equals(user.getUsername())){
int id = user.getId();
BeanUtils.copyProperties(mockUser,user);
user.setId(id);
updateUsers.add(user);
}else{
User newUser = new User();
BeanUtils.copyProperties(mockUser,newUser);
addUsers.add(newUser);
}
}
}

}

用這種方法,我在測試環(huán)境壓了30萬條數(shù)據(jù),比對數(shù)據(jù)等了大概20分鐘后,直接OOM

2.方案二:使用布隆過濾器

即:比對開始前,先將我們這邊的數(shù)據(jù)壓入布隆過濾器,然后通過布隆過濾器來判定接口數(shù)據(jù)

示例

@Override
public void compareAndSave(List<User> users,List<MockUser> mockUsers){
List<User> addUsers = new ArrayList<>();
List<User> updateUsers = new ArrayList<>();
BloomFilter<String> bloomFilter = getUserNameBloomFilter(users);
for (MockUser mockUser : mockUsers) {
boolean isExist = bloomFilter.mightContain(mockUser.getUsername());
//更新
if(isExist){
User user = originUserMap.get(mockUser.getUsername());
int id = user.getId();
BeanUtils.copyProperties(mockUser,user);
user.setId(id);
updateUsers.add(user);
}else{
User user = new User();
BeanUtils.copyProperties(mockUser,user);
addUsers.add(user);
}
}

}

用這種方法,我在測試環(huán)境壓了30萬條數(shù)據(jù),比對耗時1秒左右

3.方案三:使用list + map比對

即:比對開始前,先將我們這邊數(shù)據(jù)存放到map中,map的key為username,value為用戶數(shù)據(jù),然后遍歷接口數(shù)據(jù),進行比對

示例

@Override
public void compareAndSave(List<User> users, List<MockUser> mockUsers) {
Map<String,User> originUserMap = getOriginUserMap(users);
List<User> addUsers = new ArrayList<>();
List<User> updateUsers = new ArrayList<>();
for (MockUser mockUser : mockUsers) {
if(originUserMap.containsKey(mockUser.getUsername())){
User user = originUserMap.get(mockUser.getUsername());
int id = user.getId();
BeanUtils.copyProperties(mockUser,user);
user.setId(id);
updateUsers.add(user);
}else{
User user = new User();
BeanUtils.copyProperties(mockUser,user);
addUsers.add(user);
}
}
}

用這種方法,我在測試環(huán)境壓了30萬條數(shù)據(jù),比對耗時350毫秒左右

04 總結(jié)

這三種方案,兩層循環(huán)效率是最低,而且隨著數(shù)據(jù)量增大會有OOM的風險。采用布隆過濾器,存在誤判的風險,為了降低誤判風險,只能降低誤判率,可以通過參數(shù)指定,但這也增加判斷時間。用map可以說是效率最好,他本質(zhì)是將時間復雜度從O(n2)降低到O(n)。不過這種方案可能也不是最優(yōu)方案,事后和朋友討論下,他說可以用啥雙向指針啥,因為我在算法這方面沒有深入研究,因此本文就沒演示了

05 demo鏈接

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-comparedata。

責任編輯:張燕妮 來源: Linyb極客之路
相關(guān)推薦

2009-12-08 09:21:13

WCF數(shù)據(jù)量

2024-11-15 09:54:58

2025-01-23 00:00:00

JMMJava

2011-04-18 11:13:41

bcp數(shù)據(jù)導入導出

2024-01-23 12:56:00

數(shù)據(jù)庫微服務(wù)MySQL

2017-11-22 15:33:56

MySQL快速插入語句優(yōu)化

2019-09-27 12:44:03

數(shù)據(jù)建模企業(yè)數(shù)據(jù)存儲

2024-07-30 15:56:42

2013-12-18 11:11:43

UPYUN數(shù)據(jù)

2021-01-07 07:46:34

MyBatis 數(shù)據(jù)量JDBC

2018-06-01 09:42:43

數(shù)據(jù)Spark規(guī)模

2021-04-07 10:20:31

MySQL數(shù)據(jù)庫命令

2016-10-19 09:25:46

數(shù)據(jù)庫OracleMySQL

2024-11-13 15:22:36

Python列表切片

2013-11-20 16:29:41

SAP中國商業(yè)同略會DVM

2020-07-19 10:53:42

數(shù)據(jù)庫MySQL遷移

2022-08-14 14:52:45

數(shù)據(jù)存儲實踐

2011-03-03 10:32:07

Mongodb億級數(shù)據(jù)量

2013-01-11 09:39:56

WLAN3GLTE

2020-06-29 19:15:54

MySQL 數(shù)據(jù)量性能
點贊
收藏

51CTO技術(shù)棧公眾號