在 Spring Boot 中创建一个创建数据任务的不同性能,Postgres



我试图在创建数据后重新加载数据,但与创建相比,重新加载任务需要很长时间。

性能: CSV 文件:1,2k 条记录。 首次将数据插入表中:15.413022393 秒 然后,我删除所有数据: 1.196959342 秒 然后,我第二次使用相同的功能将数据插入表中,相同的csv文件: 52.934162753 秒

总结:第一次:15.4秒,第二次:52.9秒。 当我更改包含 66k 条记录的 csv 文件时,我得到苦涩的结果: 第一次:15分钟,第二次:约2小时。

您知道为什么同一任务需要太大的性能吗?我应该怎么做才能获得与第一次相同的第 2 次性能。

这是我的源代码:

public class EtlApplication implements CommandLineRunner {
public static boolean acessDB = true;
@Autowired
ProcessDataController processDataController;
public static void main(String[] args) {
SpringApplication.run(EtlApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
acessDB = false;
processDataController.createData();
acessDB = true;
}

}

过程数据和测试

public class ProcessDataController {
public static final String CSV_URL = "C:\abc.csv";
List<CSVSales> data = new ArrayList<>();
@Autowired
private ARepository aRepository;
@Autowired
private BRepository bRepository;
@Autowired
private CRepository cRepository;
@Autowired
private DRepository dRepository;
@Autowired
private ERepository eRepository;
@Autowired
private FRepository fRepository;
@Autowired
private GRepository gRepository;
@Autowired
private HRepository hRepository;
@Autowired
private IRepository iRepository;
@Autowired
private KRepository kRepository;
@Autowired
private LRepository lRepository;
public void createData() throws IOException, ParseException {
// BEGIN - For TESTING
long step[] = new long[20];
double timer[] = new double[20];
ArrayList<String> table = new ArrayList<>();
table.add("A");
table.add("B");
table.add("C");
table.add("D");
table.add("E");
table.add("F");
table.add("G");
table.add("H");
table.add("I");
table.add("K");
table.add("L");
// END - For TESTING
CSVReadAndParse readAndParse = new CSVReadAndParse();
readAndParse.setUrl(CSV_URL);
step[0] = System.nanoTime();
data = readAndParse.getResult();
step[1] = System.nanoTime();
timer[0] = step[1] - step[0];
for (int num = 0; num < data.size(); num++) {
step[0] = System.nanoTime();
A a = new A(data.get(num).getACode(), data.get(num).getAName());
aRepository.save(a);
step[1] = System.nanoTime();
timer[1] += step[1] - step[0];

B b = new B(data.get(num).getBCode(), data.get(num).getBName());
bRepository.save(b);
step[2] = System.nanoTime();
timer[2] += step[2] - step[1];
C c = new C(data.get(num).getC());
cRepository.save(c);
step[3] = System.nanoTime();
timer[3] += step[3] - step[2];
D d = new D(data.get(num).getDCode(), data.get(num).getDName());
dRepository.save(d);
step[4] = System.nanoTime();
timer[4] += step[4] - step[3];
E e = new E(data.get(num).getECode(), data.get(num).getEName());
eRepository.save(e);
step[5] = System.nanoTime();
timer[5] += step[5] - step[4];
F f = new F(data.get(num).getF());
fRepository.save(month);
step[6] = System.nanoTime();
timer[6] += step[6] - step[5];
G g = new G(data.get(num).getGCode(), data.get(num).getGName());
gRepository.save(g);
step[7] = System.nanoTime();
timer[7] += step[7] - step[6];
H h = new H(data.get(num).getHCode(), data.get(num).getHName());
pRepository.save(h);
step[8] = System.nanoTime();
timer[8] += step[8] - step[7];
I i = new I(data.get(num).getICode(), data.get(num).getIName());
iRepository.save(i);
step[9] = System.nanoTime();
timer[9] += step[9] - step[8];
K k = new K(data.get(num).getK());
kRepository.save(k);
step[10] = System.nanoTime();
timer[10] += step[10] - step[9];

L l = new L();
L.setA(data.get(num).getNumberOfSale());
L.setB(data.get(num).getSalesAmount());
l.setC(a);
l.setC(b);
l.setD(c);
l.setE(d);
l.setF(e);
l.setG(f);
l.setH(g);
l.setI(h);
l.setK(i);
fRepository.save(l);
step[11] = System.nanoTime();
timer[11] += step[11] - step[10];
}
double sum = 0;
for (int i = 1; i <= 11; i++) {
System.out.println(table.get(i - 1) + " time: " + new DecimalFormat("#.##########").format(timer[i] / 1000000000) + " seconds");
sum += timer[i];
}
System.out.println("Reading data time: " + new DecimalFormat("#.##########").format(timer[0] / 1000000000) + " seconds");
System.out.println("Total creating table time: " + new DecimalFormat("#.##########").format(sum / 1000000000) + " seconds");
}
public void deleteAllData() {
lRepository.deleteAll();
aRepository.deleteAll();
bRepository.deleteAll();
cRepository.deleteAll();
eRepository.deleteAll();
fRepository.deleteAll();
gRepository.deleteAll();
hRepository.deleteAll();
iRepository.deleteAll();
kRepository.deleteAll();
}
@RequestMapping(value = "/api/reloadData", method = RequestMethod.GET)
public  String reloadData() throws IOException, ParseException {
System.out.println("------------------------" + acessDB);
if (acessDB) {
acessDB = false;
long step1 = System.nanoTime();
deleteAllData();
long step2 = System.nanoTime();
createData();
long step3 = System.nanoTime();
double time1 = ((double) (step2 - step1) / 1000000000);
double time2 = ((double) (step3 - step2) / 1000000000);
double time3 = ((double) (step3 - step1) / 1000000000);
System.out.println("Delete time: " + new DecimalFormat("#.##########").format(time1) + " Seconds");
System.out.println("Create time: " + new DecimalFormat("#.##########").format(time2) + " Seconds");
System.out.println("Total time: " + new DecimalFormat("#.##########").format(time3) + " Seconds");
acessDB = true;
return "Done";
} else {
return "Busy";
}
}

}

如果你有任何想法,请帮助我。谢谢大家的支持。


1,2k 条记录的结果

第一次

时间:1.447862537秒

B时间:1.255404293 秒

时间:1.394218887 秒

D时间:1.187494522秒

E时间:1.181336583秒

F 时间:1.259357541 秒

G 时间:1.2722146 秒

H 时间:1.276657592 秒

I 时间:1.238350482 秒

K 时间:1.132834423 秒

L 时间:2.767290933 秒

读取数据时间:0.017714579秒

总创建表时间:15.413022393 秒


第二次

时间:4.452199036秒

B 时间:4.602505654 秒

C 时间:4.847908167 秒

D 时间:4.424638278 秒

E时间:4.820910787秒

F时间:5.235425021秒

G 时间:5.069998945 秒

H 时间:5.022227053 秒

I 时间:4.918734423 秒

K时间:4.483681708秒

L 时间:5.04199453 秒

读取数据时间:0.008831614秒

总创建表时间:52.920223602 秒

删除时间:1.196959342 秒

创建时间:52.934162753秒

总时间: 54.131122095 秒

在保存实体之前,我尝试通过以下方式连接实体管理器:

@Autowired
private EntityManager entityManager;

然后,不要使用保存函数,而是使用保存和刷新函数。

之后,使用entityManager.clear();

最新更新