2015-10-17 60 views
0

我有一个代码将播放器数据从条目上传到MySQL数据库。查询看起来是这样的:Java MySQL更新优化

  uploadPlayers = getManager().getMysqlManager().getConnection().prepareStatement("UPDATE players SET name=?, ips=?, gamemode=?, lastlogin=?, timeplayed=?, rank=?, badges=?, level=? WHERE uuid=?"); 

以及上传玩家的方法是这样的:

@Override 
public void saveDataToDatabase() { 
    try{ 
     for (final Entry<String, IPlayerData> entry : playerdatalist.entrySet()) { 
      final IPlayerData pd = entry.getValue(); 

      SH.uploadPlayers.setString(1, pd.getName()); 
      SH.uploadPlayers.setString(2, pd.getIp()); 
      SH.uploadPlayers.setInt(3, pd.getGamemode()); 
      SH.uploadPlayers.setString(4, SH.getManager().getMysqlManager().getDate(pd.getLastlogin())); 
      SH.uploadPlayers.setLong(5, pd.getTimeplayed()); 
      SH.uploadPlayers.setInt(6, pd.getRank()); 
      SH.uploadPlayers.setString(7, pd.getBadgesAsString()); 
      SH.uploadPlayers.setInt(8, pd.getLevel()); 
      SH.uploadPlayers.setString(9, pd.getUUID()); 
      SH.uploadPlayers.addBatch(); 


     } 
     SH.uploadPlayers.executeBatch(); 
    }catch(SQLException e){ 
     e.printStackTrace(); 
    } 

有一个在入境和在数据库中大约1500个的球员。 但每次使用代码时,它会使用15-20秒更新所有玩家。 我怎样才能让它走得更快并优化它?

+0

将数据上传到临时表中。然后使用'join'做一个'update'语句。如果数据不在数据库中,那么'load data infile'是一种获取数据的快速方法。 –

+0

你有'uuid'列索引吗? –

+0

不,我没有索引uuid列,但不仅仅有助于选择? –

回答

1

您需要在uuid列上创建索引。

没有指标,批中的每个条目的数据库引擎将不得不通过表中的所有行来确定更新哪一行,让你在(更新行数)的规模的时间复杂度 * (表中所有行的数量)。使用索引时,时间复杂度将下降至的行数,仅更新的行数。

添加索引将要加收(时间)成本的更新和插入,但相比于改善这将是微不足道的,如果你总是为自己uuid(你可能是)更新行。

1

这里有两个问题。正如@JiriTousek所建议的,在uuid字段中没有索引会使你放慢速度(对于该答案为+1)。第二个是你正在更新所有的领域是严格需要的吗?

按照manual

UPDATE语句进行优化像一个写的 额外开销SELECT查询。写入速度取决于正在更新的数据量 以及更新的 索引数。没有更改的索引不会更新

事实上,UUID字段是charfield,长度为9个字符意味着这里的索引会大大提升。即使是部分索引也可能起作用。

manual还说:

如果设置为它当前的值的列时,MySQL注意到这 并且不更新它。

尽管如此,您不应该更新所有的字段(如果它们不是严格需要的话),因为您要传递大量数据并且绑定参数的开销也很小。

最后如果速度真的很重要@GordonLinoff建议创建一个临时表,然后用一条语句更新是一条可行的路。如果你发现即使这样慢@GordonLinoff LOAD DATA INFILE的其他建议是他们所有人的最佳选择。

+0

如果添加索引是不够的,一个很好的提示。尽管如此,实现起来还是比较困难的,所以如果索引速度仍然很慢,或者Java与数据库之间发送的数据量是令人担忧的,我只会对此感到困扰。此开销只会为每个更新的行添加一个固定时间,而不是与表大小成线性关系。 –