以前的信息:數據庫遠程託管,平均延遲92ms連接。Java mysql - SELECT語句延遲主線程
我有一個小小的MySQL數據庫,它爲我的遊戲存放玩家數據。
當遍歷結果集時,每個玩家返回250行,在玩家登錄遊戲時分配玩家變量。
我的問題是,每次玩家登錄時,我的遊戲主線程會延遲一段時間,大約200毫秒。 (每個遊戲週期有600ms)。
我發現這只是發生在SELECT語句中,所有其他查詢如UPDATE,DELETE或任何不返回ResultSet的查詢都很好。
我使用的C3P0 MySQL的游泳池,這是我的configs它:
cpds.setInitialPoolSize(100);
cpds.setMinPoolSize(100);
cpds.setNumHelperThreads(200);
cpds.setMaxIdleTime(0);
cpds.setAcquireIncrement(10);
cpds.setMaxPoolSize(200);
cpds.setMaxStatements(0);
每次在大約10查詢執行,各地請求其他玩家的信息,他們當前聊天服務器玩家登錄等等。這些查詢不能在單個語句中發佈,這就是c3p0中多個線程和連接的原因,以減少滯後,這非常有效。
正如我所說,它只發生在期望ResultSet的SELECT查詢中。
問題是:我將如何運行該查詢,將結果賦予播放器變量,所有這些都不會將主線程搞亂200ms?
200ms可能會顯示「ok」,但如果50個玩家同時登錄,該怎麼辦?這只是將時間乘以創建一個巨大的線程鎖。
我是怎麼裝的玩家:
在登錄,這要求:
PlayerLoader.load(username);
所以它返回Player實例下面的方法,被稱爲:
public static Player load(String name) {
ResultSet result = null;
PreparedStatement ps = null;
Player player = new Player();
Connection con = null;
try {
con = World.database().getConnection();
ps =con.prepareStatement("SELECT * FROM " + PLAYER_TABLE + " WHERE username='" + name + "' LIMIT 1");
result = ps.executeQuery();
if (result.next()) {
return player.playerSaving().load(result);
}
} catch (Exception e) {
System.err.println("Error Loading the account: "+name);
e.printStackTrace();
} finally {
try {
if (result != null) {
result.close();
}
result = null;
ps.close();
ps = null;
con.close();
} catch (SQLException e) {
}
}
return null;
}
後獲取ResultSet,另一個方法被調用,它將變量分配給播放器實例。
該方法包括:
player.getPlayerDefinition().getIndex(result.getShort("id")).setDisplayName(result.getString("displayName"));
player.getPlayerDefinition().setRights(result.getShort("rights"));
player.getPlayerDefinition().setPlayTime(result.getLong("playTime"));
player.getPlayerDefinition().setMuted(result.getInt("mute")).setMuteDuration(Long.parseLong(result.getString("muteTill")));
player.getPlayerDefinition().setBanned(result.getLong("banned"));
player.getPlayerDefinition().setPermBanned(result.getString("permBanned").equals("true"));
player.getPlayerDefinition().setMemberDays2(result.getLong("member_days"));
這是它只是一個短版。目前它加載全部250行。
該方法還返回Player實例,所以第一個Load方法將返回它。 (請參閱:public Player load(ResultSet result)
)
經過該過程後,創建實例並準備繼續,現在玩家請求關於他們的世界,聊天服務器等的信息,這就是大約6-7個執行得非常快的小查詢。大約2-3個查詢是帶有簡短結果的SELECT語句。
同樣,有什麼辦法可以在異步線程中運行該加載過程嗎?如果是的話,怎麼樣?
謝謝。
我目前使用五個專用服務器。其中4家位於加拿大,主要的一家,即主辦的數據庫位於美國。 我試圖讓遠程性能很好,因爲我正要在亞洲獲得更多的服務器,因爲在那個位置有ping。但是,無論客戶端位於何處,數據庫加載都必須快速。 – 2015-02-17 23:37:52