JDBC FOR UPDATE查询需要120Ms + PER ROW

时间:2017-11-18 22:43:47

标签: java performance jdbc sql-update

我正在运行以下代码从数据库中提取记录,然后将记录标记为正在读取。

public static Future<DBEntry[]> mark(int num) {
    return slaveDriver.submit(new DBSlave() {
        @Override
        public DBEntry[] run(Connection con, DBEntry[] entries) throws SQLException {
            try {
                con.setAutoCommit(false);
                String query = "SELECT `email`,`pass`,`status` FROM `" + DB_TABLE + "` WHERE `status`='fresh' AND `script`='test' ORDER BY `" + DB_TABLE +
                               "`.`lastseen` ASC LIMIT ? FOR UPDATE";
                try (PreparedStatement ps = con.prepareStatement(query, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
                    ps.setInt(1, num);
                    ResultSet rs = ps.executeQuery();
                    DBEntry[] entry = valueOf(rs);
                    while (rs.next()) {
                        rs.updateString(3, "used");
                        rs.updateRow();
                    }
                    con.commit();
                    return entry;
                }
            } finally {
                con.setAutoCommit(true);
            }
        }
    });
}

protected static Connection getConnection(boolean rbs) throws SQLException {
    Connection conn = slavePool.poll();
    if (conn == null) {
        conn = DriverManager.getConnection(URL + DB_NAME + (rbs ? "?rewriteBatchedStatements=true" : null), DB_USER, DB_PASS);
    }
    return conn;
}

public static DBEntry[] valueOf(ResultSet set) throws SQLException {
    int rowcount = 0;
    if (set.last()) {
        rowcount = set.getRow();
        set.beforeFirst();
    }
    DBEntry[] entries = new DBEntry[rowcount];
    for (int i = 0; set.next(); i++) {
        entries[i] = new DBEntry(null, set.getString(1), set.getString(2), "", "", 0, 0, null);
    }
    set.beforeFirst();
    return entries;
}

我的数据库:

enter image description here

正在远程完成操作。机器通过1gbps线连接,所以理论上我几乎可以即时下载所有记录。但是,使用上面的代码,每行需要120M以上,2700行需要320秒。 (所有测试行小于0.5Mb)

我做错了什么或这是预期的表现吗?

另外我应该注意,这需要能够同时运行多个实例而不会破坏记录或删除重复项,这就是此代码的原因:

ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE

同样,以下代码似乎可以显着加快所有批处理查询的过程,这就是包含它的原因:

rewriteBatchedStatements=true

我可以根据请求发布一个可运行的示例,但我确定延迟不是由程序的任何其他部分引起的,因为它在&#34;标记&#34;方法

任何帮助非常感谢!

0 个答案:

没有答案
相关问题