使用createNativeQuery的性能问题

时间:2017-09-20 14:11:54

标签: java oracle hibernate jpa ejb

我遇到了性能问题,但是,尽管它在主题中提出了建议,但可能并不是我使用的是createNativeQuery。我有一个相当大的查询,我作为字符串传递给createNativeQuery。该查询包含多个JOIN,并与5个实体相关联。该查询平均需要20 - 25秒才能运行。我已经尝试过,比如尝试使用createQuery方法并使用setFlushMode(FlushModeType.COMMIT),setMaxResults()和setFirstResult()方法,但没有区别。

我们在JTA容器管理的环境中使用JBoss EAP 6.2,使用EJB 3.0,JPA 2.1,Hibernate 4.2。我使用的IDE是NetBeans 8.0.2

然而,如果我直接在像DB Visualizer这样的SQL工具中运行查询,则需要几毫秒。我怀疑它可能与Hibernate有关,但我不确定。虽然在表之间存在特定关系,但实体类中没有一个包含集合,如查询中的JOIN语句所示。我在下面附上了一些代码(包括查询)。

我希望按原样保留查询,但如果提出的建议可以提高效率,我会对此持开放态度。我很欣赏它可能很难回答,因为在不知道数据库模式的情况下,下面的查询可能很难分析(这是一个公司项目,因此在某些情况下只能提供伪代码)。我还没有提供Entity或Facade类,但可以在以后提供这些类。任何帮助将不胜感激。谢谢!

public List<String> searchSingleView (String sourceSystem, String sourceClientId, String convertedClientId, String policyNum) {

   String sqlQuery = "SELECT DISTINCT " +
      "MDMCUST_ORS.C_BO_PARTY_XREF.ROWID_XREF, " +                                      "MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM, " +
                                    "MDMCUST_ORS.C_BO_CONTRACT.SRC_POLICY_ID, " +
                                    "MDMCUST_ORS.C_BO_CONTRACT.ISSUE_DT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID, " +
                                    "MDMCUST_ORS.C_BO_PARTY_XREF.PERS_FULL_NAME_TXT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_XREF.PERS_SRC_NAME_TXT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_XREF.ORG_LEGAL_NAME_TXT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_XREF.ORG_SRC_NAME_TXT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_XREF.ORG_LEGAL_SFX_TXT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_XREF.ORG_NAME_TXT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_XREF.SIN_BIN_TEXT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_XREF.PERS_BIRTH_DT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.LAST_UPDATE_DATE, " +
                                    "MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.COMPLETE_ADDRESS_TXT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.TOPLINE_POSTAL_ADDR_TXT, " +
                                    "MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.CITY_NAME, " +
                                    "MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.COUNTRY_NAME, " +
                                    "MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.POSTAL_CD, " +
                                    "MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.POSTAL_ADDR_PURPOSE_CD, " +
                                    "MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.STATE_PROVINCE_NAME, " +
                                    "MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.BAD_ADDR_IND " +
                                    "FROM MDMCUST_ORS.C_BO_PARTY_XREF " +
                                    "LEFT JOIN MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF ON " + 
                                    "(MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.S_PARTY_ROWID = MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID " +
                                        "OR MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.S_PARTY_ROWID = MDMCUST_ORS.C_BO_PARTY_XREF.CONVERTED_CLIENT_ID) " +      
                                    "LEFT JOIN MDMCUST_ORS.C_LU_CODES ON MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.POSTAL_ADDR_PURPOSE_CD = MDMCUST_ORS.C_LU_CODES.CODE " +
                                    "LEFT JOIN MDMCUST_ORS.C_BO_PARTY_REL ON MDMCUST_ORS.C_BO_PARTY_XREF.ROWID_OBJECT = MDMCUST_ORS.C_BO_PARTY_REL.FROM_PARTY_ROWID " +
                                    "LEFT JOIN MDMCUST_ORS.C_BO_CONTRACT ON MDMCUST_ORS.C_BO_PARTY_REL.CONTRACT_ROWID = MDMCUST_ORS.C_BO_CONTRACT.ROWID_OBJECT " +
                                "WHERE MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM IN ('E-CAPSIL', 'C-CAPSIL', 'INGENIUM') " +
                                    "AND (UPPER(MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID) = ? " +
                                    "     OR UPPER(MDMCUST_ORS.C_BO_PARTY_XREF.CONVERTED_CLIENT_ID) = ? " +
                                    "     ) " +
                                    "AND UPPER(MDMCUST_ORS.C_BO_CONTRACT.SRC_POLICY_ID) = ? " +
                                    "AND MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.POSTAL_ADDR_PURPOSE_CD = '56|07'" +
                                    "AND MDMCUST_ORS.C_BO_PARTY_XREF.HUB_STATE_IND = '1' " +
                                    "AND MDMCUST_ORS.C_BO_CONTRACT.HUB_STATE_IND = '1' " +
                                    "AND MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR_XREF.HUB_STATE_IND = '1' " + 
                                    "AND MDMCUST_ORS.C_LU_CODES.HUB_STATE_IND = '1'" +
                                    "AND ROWNUM = 1";

try {
            querySingleView = emSingleView.createNativeQuery(sqlSingleViewQuery)
                                          .setParameter(1, sourceClientId)
                                          .setParameter(2, convertedClientId)
                                          .setParameter(3, policyNum);
            querySingleViewResult = (List<String>) querySingleView.getResultList();
        } catch (NoResultException nre) {
          // Issue a validation failure message to prevent query from continuing.
            FacesContext.getCurrentInstance().validationFailed();
            // Display error message to user
            JsfUtil.addErrorMessage(ResourceBundle.getBundle("/Bundle").getString("fatcaSearchSingleViewFailMessage"));
            // Generate log entry on server
            java.util.logging.Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, nre);
        }
        return querySingleViewResult;
    }

1 个答案:

答案 0 :(得分:0)

UPPER(MDMCUST_ORS.C_BO_CONTRACT.SRC_POLICY_ID) = ? " 

很可能会阻止Oracle在SRC_POLICY_ID上使用索引。如果它是一个ID,我希望它是一个数字,所以UPPER不是必需的。如果你确实需要UPPER而不是你应该在列上创建一个基于函数的索引。

但是无法访问数据库性能问题很难解决。

P.S。:你真的需要DISTINCT和ROWNUMBER = 1。我认为你应该通过使用WHERE子句中的适当条件来编写只获得一行的查询。