2015-10-17 54 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與數據庫之間發送的數據量是令人擔憂的,我只會對此感到困擾。此開銷只會爲每個更新的行添加一個固定時間,而不是與表大小成線性關係。 –