【发布时间】:2016-12-26 23:15:17
【问题描述】:
我有一个包含超过 100 万行的用户表(Oracle 11g DB),其中包含我尝试使用 SHA512 算法(散列和盐)散列的所有用户密码。下面开始是我的 Java 类,用于读取用户表中的所有记录,对其进行哈希处理并更新回用户表。
- 我正在为 SELECT 和 UPDATE 查询使用准备好的语句
- 我已将准备好的语句提取大小设置为 1000 (
setFetchSize(1000)) - 我已将自动提交属性设置为 false
- 使用批处理方式进行批量更新
try {
ps = con.prepareStatement("update user set password=? where ID=?");
psSel = con.prepareStatement("select ID, password from user");
psSel.setFetchSize(1000);
rs = psSel.executeQuery();
String hashPassword = null;
while (rs.next()) {
long id = rs.getLong(1);
String pwd = rs.getString(2);
hashPassword = <<CALL TO PASSWORD HASHING UTIL>>;
ps.setString(1, hashPassword);
ps.setLong(2, id);
ps.addBatch();
//Every 5000 records update and commit
if(++count % batchSize == 0) {
ps.executeBatch();
con.commit();
}
}
ps.executeBatch();
con.commit();
} catch (SQLException e) {
e.printStackTrace();
}
更新100,000条记录,上面的方法需要将近8分钟,我觉得相当高。
使用的数据库: Oracle 11g
Java 版本: 1.6
环境:Windows 7
我不确定我是否遗漏了什么。您能否建议或推荐任何处理此类批量负载的最佳方法?
更新
我再次查看了我之前创建的 USER 临时表,可以看到 ID 列中没有添加 主键约束。我继续为 ID 列添加 PK 约束并重新运行我的实用程序。现在处理 100,000 行只需要 36 秒。
为了确保我还创建了另一个没有 PK 约束的临时表 USER_TMP2 并运行了我的实用程序,它像往常一样花了 8 分钟 100,000 >
【问题讨论】:
-
8 分钟 hash 并在 DB 中更新 100 万条记录似乎并不高
-
你能在数据库端复制你的哈希函数吗?如果是这样,您可以进行一次更新,而无需通过网络将所有数据移入和移出 Java。但目前尚不清楚瓶颈在哪里。
-
为什么不在
DBMS_CRYPTO中使用HASH_SH512? -
您是否进行了任何基本调试,例如分析代码?就你所知,数据库的东西用了 0.1 秒,另外 7 分钟 59.9 秒用在了你的哈希函数中。
-
@Sachin - 您可以编写一个 Java 存储过程,该过程使用 Java 的散列功能但在数据库中运行,这当然假设盐可用于数据库。而网络旅行实际上是瓶颈。
标签: java oracle jdbc oracle11g batch-processing