【问题标题】:Need to optimize the query to insert the record需要优化查询以插入记录
【发布时间】:2019-01-27 08:21:28
【问题描述】:

我写了一段JDBC模板代码,在表中插入记录,但问题是我的执行卡在这个特定的sn-p上,似乎某种挂起。我没有弄清楚原因,因为查询在 sqldeveloper 中正常运行

List<SalaryDetailReport> reports = salaryDetailReportDAO.findAll(tableSuffix, regionId, circleId);
// the above line find the required data, if data is found then it proceeds

if (reports != null && reports.size() > 0) {
    for (SalaryDetailReport salaryDetail : reports) {
        try {
            SalaryDetail sd = new SalaryDetail();
            sd.setDetailReport(salaryDetail);
            salaryDetailDAO.save(sd, tableSuffix);
        } catch (Exception e) {
            log.error("Error occured", e);
            e.printStackTrace();
            throw new MyExceptionHandler(" Error :" + e.getMessage());
        }
    }

    System.out.println("data found");

} else {
    log.error("Salary Record Not Found.");
    throw new MyExceptionHandler("No record Found.");
}

你们看到了 try-catch ,我的执行卡在 try 和 catch 中,这是我的实现类中的插入代码。当我评论上面的代码时,我的应用程序工作正常,但是为什么我的应用程序卡在这里,我无法弄清楚,请帮助我

@Override
public void save(SalaryDetail details, String tableSuffix) {
    String tabName = "SALARY_DETAIL_" + tableSuffix;
//  String q = "INSERT INTO " + tabName + "(ID "
    String q = "INSERT INTO SALARY_DETAIL_TBL "
            + "                  (ID "
            + "                  ,EMP_NAME "
            + "                  ,EMP_CODE "
            + "                  ,NET_SALARY "
            + "                  ,YYYYMM "
            + "                  ,PAY_CODE "
            + "                  ,EMP_ID "
            + "                  ,PAY_CODE_DESC "
            + "                  ,REMARK "
            + "                  ,PAY_MODE ) "
            + "          (SELECT (sd.SALARY_REPORT_ID) ID "
            + "                  ,(sd.emp_name) emp_name "
            + "                  ,(sd.EMP_CODE) EMP_CODE "
            + "                  ,(sd.amount) NET_SALARY "
            + "                  ,(sd.YYYYMM) YYYYMM "
            + "                  ,(sd.pay_code) pay_code "
            + "                  ,(sd.emp_id) emp_id "
            + "                  ,(sd.PAY_CODE_DESC) PAY_CODE_DESC "
            + "                  ,(sd.REMARK) REMARK "
            + "                  ,(sd.PAY_MODE)PAY_MODE "
//          + "            FROM SALARY_DETAIL_REPORT_" + tableSuffix + " sd "
            + "            FROM SALARY_DETAIL_REPORT_TBL sd "
            + "            WHERE sd.PAY_CODE = 999 "
            + "            AND sd.EMP_ID IS NOT NULL "
//          + "            AND sd.EMP_ID NOT IN  (SELECT EMP_ID FROM SALARY_DETAIL_" + tableSuffix + ") "
            + "            AND sd.EMP_ID NOT IN  (SELECT EMP_ID FROM SALARY_DETAIL_TBL) "
            + "            ) ";

    MapSqlParameterSource param = new MapSqlParameterSource();
    param.addValue("id", details.getId());
    param.addValue("EMP_NAME", details.getEmpName());
    param.addValue("EMP_CODE", details.getEmpCode());
    param.addValue("NET_SALARY", details.getNetSalary());
    param.addValue("GROSS_EARNING", details.getGrossEarning());
    param.addValue("GROSS_DEDUCTION", details.getGrossDeduction());
    param.addValue("YYYYMM", details.getYyyymm());
    param.addValue("EMP_ID", details.getEmployee() != null ? details.getEmployee().getEmpId() : null);
    KeyHolder keyHolder = new GeneratedKeyHolder();
    getNamedParameterJdbcTemplate().update(q, param);
//  details.setId(((BigDecimal) keyHolder.getKeys().get("ID")).longValue());
}

【问题讨论】:

  • 查询中不需要声明参数吗?喜欢WHERE ID = :id?您应该在 SQLDeveloper 等数据库管理工具中尝试查询。

标签: java sql jdbctemplate


【解决方案1】:

主要问题在于您的查询是 Not In 条件。它会降低你的表现。尝试在单独的查询中获取“SELECT EMP_ID FROM SALARY_DETAIL_TB”,并在主查询中传入 Not in 块。这将提高查询的性能。每次执行保存时,每次都会触发选择查询。

【讨论】:

    【解决方案2】:

    您必须决定是从SELECT 还是从应用程序插入记录。


    如果您不需要在选择后处理数据,那么您可以简单地调用一个INSERT INTO SELECT 语句而无需任何for 循环。因为只有一个 INSERT 语句调用,所以它会很快。

    因此,您将在您的SalaryDetailReportDAO 中实现类似copyAllInSalaryDetail(tableSuffix, regionId, circleId) 的方法,并且该方法将使用与findAll() 方法中相同的WHERE 条件执行INSERT INTO salary_detail_tbl... (...) (SELECT ... WHERE ...)。所有插入将仅在数据库层上完成。


    如果您想在插入数据之前对其进行操作,您可以使用SalaryDetail bean 和for 循环继续您的方法,但您应该从INSERT 语句中删除SELECT 部分并使用来自提供豆。那么save() 方法可以如下所示:

    @Override
    public void save(SalaryDetail details, String tableSuffix) {
        // use tableSuffix if it is really needed
        String q = "INSERT INTO SALARY_DETAIL_TBL "
                + "                  (ID "
                + "                  ,EMP_NAME "
                + "                  ,EMP_CODE "
                + "                  ,NET_SALARY "
                + "                  ,YYYYMM "
                + "                  ,PAY_CODE "
                + "                  ,EMP_ID "
                + "                  ,PAY_CODE_DESC "
                + "                  ,REMARK "
                + "                  ,PAY_MODE ) "
                + "          VALUES (:id "
                + "                  ,:emp_name "
                + "                  ,:emp_code "
                + "                  ,:net_salary "
                + "                  ,:yyyymm "
                + "                  ,:pay_code "
                + "                  ,:emp_id "
                + "                  ,:pay_code_desc "
                + "                  ,:remark "
                + "                  ,:pay_mode)";
    
        MapSqlParameterSource param = new MapSqlParameterSource();
    //    KeyHolder keyHolder = new GeneratedKeyHolder();
    //  details.setId(((BigDecimal) keyHolder.getKeys().get("ID")).longValue());
        param.addValue("id", details.getId());
        param.addValue("emp_name", details.getEmpName());
        param.addValue("emp_code", details.getEmpCode());
        param.addValue("net_salary", details.getNetSalary());
        param.addValue("pay_code", details.getPayCode());
        param.addValue("pay_code_desc", details.getPayCodeDesc());
        param.addValue("pay_mode", details.getPayMode());
        param.addValue("remark", details.getPayRemark());
        param.addValue("yyyymm", details.getYyyymm());
        param.addValue("emp_id", details.getEmployee() != null ? details.getEmployee().getEmpId() : null);
        getNamedParameterJdbcTemplate().update(q, param);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-15
      • 1970-01-01
      • 2020-12-31
      • 1970-01-01
      • 2016-02-02
      • 2014-03-05
      相关资源
      最近更新 更多