【问题标题】:using JPA, method is taking a 60 sec使用 JPA,方法需要 60 秒
【发布时间】:2020-04-02 11:47:30
【问题描述】:

我正在使用 JPA,我的 Web 应用程序需要 60 秒来执行此方法,我想更快地执行它如何实现?

public boolean evaluateStudentTestPaper (long testPostID, long studentID, long howManyTimeWroteExam) {

    Gson uday = new Gson();
    Logger custLogger = Logger.getLogger("StudentDao.java");
    // custLogger.info("evaluateTestPaper test paper for testPostID: " +
    // testPostID);

    long subjectID = 0;

    // checking in table
    EntityManagerFactory EMF = EntityManagerFactoryProvider.get();
    EntityManager em = EMF.createEntityManager();
    List<StudentExamResponse> studentExamResponses = null;

    try {
        studentExamResponses = em
                .createQuery(
                        "SELECT o FROM StudentExamResponse o where o.studentId=:studentId And o.testPostID=:testPostID and o.howManyTimeWroteExam=:howManyTimeWroteExam")
                .setParameter("studentId", studentID).setParameter("testPostID", testPostID)
                .setParameter("howManyTimeWroteExam", howManyTimeWroteExam).getResultList();
        System.out.println("studentExamResponses--------------------------------------------------"
                + uday.toJson(studentExamResponses) + "---------------------------------------");
    } catch (Exception e) {
        custLogger.info("exception at getting student details:" + e.toString());
        studentExamResponses = null;
    }

    int studentExamResponseSize = studentExamResponses.size();

    if (AppConstants.SHOWLOGS.equalsIgnoreCase("true")) {
        custLogger.info("student questions list:" + studentExamResponseSize);
    }

    // Get all questions based on student id and test post id
    List<ExamPaperRequest> examPaperRequestList = new ArrayList<ExamPaperRequest>();
    List<Questions> questionsList = new ArrayList<Questions>();
    // StudentExamResponse [] studentExamResponsesArgs =
    // (StudentExamResponse[]) studentExamResponses.toArray();
    // custLogger.info("Total questions to be evaluated: " +
    // examPaperRequestList.size());
    List<StudentTestResults> studentTestResultsList = new ArrayList<StudentTestResults>();

    StudentTestResults studentTestResults = null;
    StudentResults studentResults = null;
    String subjectnames = "", subjectMarks = "";
    int count = 0;
    boolean lastIndex = false;

    if (studentExamResponses != null && studentExamResponseSize > 0) {
        // studentExamResponses.forEach(studentExamResponses->{

         for (StudentExamResponse o : studentExamResponses.stream().parallel()) {

           // 900 lines of coade inside which includes getting data from database Queries
    }
}

【问题讨论】:

  • 我们无法猜测是哪个代码导致了延迟。但是,如果我猜测的话,我会说它是在 900 行代码中循环执行 DB 查询,此处未显示。此外,我们不知道数据的大小——SELECT 是在获取一百万行吗?我的建议是找到一种方法来定位延误;甚至在适当的地方打印currentTimeMillis 也会有所帮助。然后看看如何优化需要优化的具体代码片段。
  • 只是将parallel() 放在steam 上并不会产生任何并行。 For 循环仍然是一个同步上下文。
  • 嗨 Lev 感谢您的建议,我收到以下错误 java.lang.NoClassDefFoundError: java.util.stream.Stream 是一个受限类。有关详细信息,请参阅 Google App Engine 开发者指南。

标签: java performance jpa


【解决方案1】:

我的猜测是您的选择查询需要时间。 如果可能,将查询超时设置为小于 60 秒并确认这一点。

设置查询超时的方法可以在这里找到 - How to set the timeout period on a JPA EntityManager query

如果这是因为查询,那么您可能需要努力使选择查询达到最佳状态。

【讨论】:

    【解决方案2】:

    正如@Nikos Paraskevopoulos 提到的,它可能应该是for 循环内的~900 * N 数据库迭代。

    我会说尽可能避免数据库迭代,特别是在这样的循环中。

    您可以尝试详细说明您当前的 StudentExamResponse sql 以包含更多子句 - 主要是您在 for 中使用的那些,这甚至可以减少您迭代的项目数量。

    【讨论】:

      猜你喜欢
      • 2017-02-24
      • 2012-03-19
      • 1970-01-01
      • 2017-06-29
      • 2017-03-23
      • 2020-03-04
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多