Различная производительность для одной задачи создания данных в Spring Boot, Postgres - PullRequest
0 голосов
/ 06 июля 2018

Я пытался перезагрузить данные после их создания, но задача перезагрузки занимает слишком много времени по сравнению с созданием.

Производительность: CSV-файл: 1,2 тыс. Записей. Впервые вставить данные в таблицу: 15.413022393 секунд Затем я удаляю все данные: 1.196959342 секунды Затем я вставляю данные в таблицу во второй раз с той же функцией, тот же CSV-файл: 52,934162753 секунды

Резюме: 1-й раз: 15,4 секунд, 2-й раз: 52,9 секунд. Когда я изменяю CSV-файл с 66k записями, я получаю горький результат: 1-й раз: 15 минут, 2-й раз: около 2 часов.

Знаете ли вы, почему для одной и той же задачи требуется слишком разная производительность? И что я должен сделать, чтобы получить производительность во 2-й раз так же, как в 1-й раз.

Вот мой исходный код:

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;
}

}

ProcessData и тест

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-й раз

Время: 1,474862537 секунд

Btime: 1,255404293 секунды

Ctime: 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 секунд


2-й раз

Время: 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 секунд

1 Ответ

0 голосов
/ 10 июля 2018

Перед сохранением сущности я попытался запустить Entity Manager по:

@Autowired
private EntityManager entityManager;

Затем, вместо использования функций сохранения, используйте функции saveAndFlush.

После этого, используя entityManager.clear();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...