嘿,我试图将大约600000个令牌包含到我的MySQL数据库表中。我正在使用的引擎是InnoDB。更新过程将永远持续下去:(。所以我最好的猜测是我在代码中完全遗漏了一些东西,而我正在做的事情只是简单的愚蠢。
也许有人对我的表现有什么看法有自发的想法:
这是我的代码:
public void writeTokens(Collection<Token> tokens){
try{
PreparedStatement updateToken = dbConnection.prepareStatement("UPDATE tokens SET `idTag`=?, `Value`=?, `Count`=?, `Frequency`=? WHERE `idToken`=?;");
for (Token token : tokens) {
updateToken.setInt(1, 0);
updateToken.setString(2, token.getWord());
updateToken.setInt(3, token.getCount());
updateToken.setInt(4, token.getFrequency());
updateToken.setInt(5, token.getNounID());
updateToken.executeUpdate();
}
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
非常感谢!
答案 0 :(得分:5)
我没有针对您的Java特定答案,而是将整个shebang包装在一个事务中。如果不这样做,则MySQL(在针对InnoDB写入时)启动并为每个更新语句提交一个新事务。
在开始调用之前执行START TRANSACTION
,并在完成所有更新/插入后执行COMMIT
。我还认为MySQL推迟了索引更新,直到事务结束,如果你要更新索引字段,这应该有助于提高性能。
答案 1 :(得分:4)
如果您的表中的一个或多个字段有索引,则每个更新都会强制重建这些索引,这可能需要一段时间才能接近数十万个条目。
PreparedStatement附带了一个addBatch()方法 - 我没有使用它,但是如果我正确使用它,你可以将几批记录传输到你准备好的语句,然后一次更新。这将索引重建的数量从600.000减少到1 - 您应该感觉不同:)
答案 2 :(得分:3)
每个更新语句都需要往返数据库。这会给你带来巨大的性能影响。
有几种方法可以将此数据插入数据库,而无需执行数十万次查询:
然后,您可以使用单个update语句将数据复制到目标表中。这将减少服务器往返次数,从而提高性能。