【问题标题】:How to optimize this update SQL query如何优化此更新 SQL 查询
【发布时间】:2012-07-26 12:05:16
【问题描述】:

我有这个 Java 方法,我将使用它来将 JSF 表单中的数据插入 Oracle:

public int saveData(int result) throws SQLException, java.text.ParseException, NoSuchAlgorithmException {

        String SqlStatement = null;

        if (ds == null) {
            throw new SQLException();
        }

        Connection conn = ds.getConnection();
        if (conn == null) {
            throw new SQLException();
        }

        PreparedStatement ps = null;

        /*

        CREATE TABLE USERS(
            USERID INTEGER NOT NULL,
            GROUPID INTEGER,
            SPECIALNUMBER VARCHAR2(60 ),
            USERNAME VARCHAR2(50 ),
            PASSWD VARCHAR2(50 ),
            DATETOCHANGEPASSWD DATE,
            ADDRESS VARCHAR2(60 ),
            STATEREGION VARCHAR2(50 ),
            COUNTRY VARCHAR2(50 ),
            USERSTATUS VARCHAR2(30 ),
            TELEPHONE VARCHAR2(50 ),
            DATEUSERADDED DATE,
            USEREXPIREDATE DATE,
            DATEUSERLOCKED CHAR(20 ),
            CITY VARCHAR2(50 ),
            EMAIL VARCHAR2(50 ),
            DESCRIPTION CLOB
        )
        /
        */

        try {
            conn.setAutoCommit(false);
            boolean committed = false;
            try {           /* insert into Oracle the default system(Linux) time */
        InsertSqlStatement = "INSERT INTO USERS"
                        + " (USERID, GROUPID, SPECIALNUMBER, USERNAME, PASSWD, DATETOCHANGEPASSWD,"
                        + " ADDRESS, STATEREGION, COUNTRY, USERSTATUS, TELEPHONE, DATEUSERADDED," 
                        + " USEREXPIREDATE, DATEUSERLOCKED, CITY, EMAIL, DESCRIPTION)"
                        + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

        UpdateSqlStatement = "UPDATE USERS "
                                + "SET "
                                    + "USERID = ?, "
                                    + "GROUPID = ?, "
                                    + "SPECIALNUMBER = ?, "
                                    + "USERNAME = ?, "
                                    + "PASSWD = ?, "
                                    + "DATETOCHANGEPASSWD = ?, "
                                    + "ADDRESS = ?, "
                                    + "STATEREGION = ?, "
                                    + "COUNTRY = ?, "
                                    + "USERSTATUS = ?, "
                                    + "TELEPHONE = ?, "
                                    + "DATEUSERADDED = ?, "
                                    + "USEREXPIREDATE = ?, "
                                    + "DATEUSERLOCKED = ?, "
                                    + "CITY = ?, "
                                    + "EMAIL = ?, "
                                    + "DESCRIPTION = ? "
                        + "WHERE USERID = " + id;

                ps = conn.prepareStatement(SqlStatement);

                ps.setString(1, settingsMap.get("USERID"));
                ps.setString(2, settingsMap.get("GROUPID"));
                ps.setString(3, settingsMap.get("SPECIALNUMBER"));
                ps.setString(4, settingsMap.get("USERNAME"));
                ps.setString(5, passwdConvert(settingsMap.get("PASSWD")));
                ps.setDate(6, toDate(settingsMap.get("DATETOCHANGEPASSWD")));
                ps.setString(7, settingsMap.get("ADDRESS"));
                ps.setString(8, settingsMap.get("STATEREGION"));
                ps.setString(9, settingsMap.get("COUNTRY"));
                ps.setString(10, settingsMap.get("USERSTATUS"));
                ps.setString(11, settingsMap.get("TELEPHONE"));
                ps.setDate(12, toDate(settingsMap.get("DATEUSERADDED")));
                ps.setDate(13, toDate(settingsMap.get("USEREXPIREDATE")));
                ps.setDate(14, toDate(settingsMap.get("DATEUSERLOCKED")));
                ps.setString(15, settingsMap.get("CITY"));
                ps.setString(16, settingsMap.get("EMAIL"));
                ps.setString(17, settingsMap.get("DESCRIPTION"));

                ps.executeUpdate();

                conn.commit();
                committed = true;
            }
            finally 
            {
                if (!committed) {
                    conn.rollback();
                }
            }
        } finally {
            /* Release the resources */
            ps.close();
            conn.close();
        }
        return result;
    }

现在我无法测试 SQL 查询。你能告诉我它是否有效以及如何优化 SQL 查询的性能?

【问题讨论】:

    标签: java sql oracle11g


    【解决方案1】:

    现在我无法测试 SQL 查询。你能告诉我它是否有效...

    不确定。 (为什么不等到可以测试呢??)

    ...以及如何优化 SQL 查询的性能?

    目前还不完全清楚您要做什么。不过,这里有一些关于性能的建议:

    • 您正在为每个执行的 SQL 语句创建和释放数据库连接。这对性能肯定是不利的。
    • 如果您打算这样做,则无需在更新同一记录后进行插入操作。
    • 您将通过批量或批量插入或更新而不是一次插入一条记录来获得性能。
    • 如果您将大量数据插入到具有大量索引的空表中,那么如果您先进行插入,然后再创建索引,则可能会获得更好的性能。

    在单个查询级别(即“更新”),您可能无法显着加快查询速度。

    【讨论】:

      【解决方案2】:

      您可以做的唯一改进是将id 设置为“?”还有:

      UPDATE USERS "
                                  + "SET "
                                      + "USERID = ?, "
                                      + "GROUPID = ?, "
                                      + "SPECIALNUMBER = ?, "
                                      + "USERNAME = ?, "
                                      + "PASSWD = ?, "
                                      + "DATETOCHANGEPASSWD = ?, "
                                      + "ADDRESS = ?, "
                                      + "STATEREGION = ?, "
                                      + "COUNTRY = ?, "
                                      + "USERSTATUS = ?, "
                                      + "TELEPHONE = ?, "
                                      + "DATEUSERADDED = ?, "
                                      + "USEREXPIREDATE = ?, "
                                      + "DATEUSERLOCKED = ?, "
                                      + "CITY = ?, "
                                      + "EMAIL = ?, "
                                      + "DESCRIPTION = ? "
                          + "WHERE USERID = ?";
      

      当然还要添加一个 set decleration:

       ps.setInt(18, id);
      

      【讨论】:

        【解决方案3】:

        我认为没有什么可以优化的,因为您只插入一张表。更新也一样。没有连接或分组,所以你真的可以做任何事情。也许只是一个注释 - 您可以使用 StringBuilder 进行代码格式化:-)

        【讨论】:

        • 在这种情况下,使用StringBuilder 将对性能产生负面影响:连接的字符串文字作为一个大字符串保存在类文件中,而StringBuilder 调用将在运行时执行。
        • 即使在运行时完成了字符串组装,Java 编译器也会在后台生成使用 StringBuilder 的代码。
        【解决方案4】:

        如果您要插入多行,那么您可以通过重用数据库连接以及准备好的语句来提高性能。后者也需要将用户 ID 视为一行,就像 ftom2 suggested 一样。除此之外,性能优化空间不大。

        【讨论】:

          猜你喜欢
          • 2021-05-24
          • 1970-01-01
          • 2022-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-27
          • 1970-01-01
          相关资源
          最近更新 更多