2014-06-17 53 views
0

我做了一個bukkit與它的MySQL插件,我需要知道爲什麼我有滯後每當這個代碼的運行運行我的系統上的服務器,並與HostGator的繼承人我的代碼MySQL服務器爲什麼我的mysql在我的Minecraft bukkit插件上滯後?

openConnection(); 
       try{ 
        int level1 = 0; 

        if(playerDataConatinsPlayer(p)){ 
         PreparedStatement sql = connection.prepareStatement("SELECT level FROM `player_data` WHERE player=?;"); 
         sql.setString(1, p.getName()); 

         ResultSet result = sql.executeQuery(); 

         result.next(); 

         level1 = result.getInt("level"); 

         PreparedStatement levelUpdate = connection.prepareStatement("UPDATE `player_data` SET level=? WHERE player=?;"); 

         levelUpdate.setInt(1, level1+1); 
         levelUpdate.setString(2, p.getName()); 
         levelUpdate.executeUpdate(); 

         levelUpdate.close(); 
         sql.close(); 
         result.close(); 
        }else{ 
         PreparedStatement newPlayer = connection.prepareStatement("INSERT INTO `player_data` values(?,0,1,0);"); 
         newPlayer.setString(1, p.getName()); 

         newPlayer.execute(); 
         newPlayer.close(); 
        } 

       }catch(Exception e1){ 
        e1.printStackTrace(); 
       }finally{ 
        closeConnection(); 
       } 

這裏我OpenConnection方法

public synchronized static void openConnection(){ 
    try{ 
     connection = DriverManager.getConnection(""); //i know its empty cause i dont wanna give that info out 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 

我的繼承人closeconnection

public synchronized static void closeConnection(){ 
    try{ 
     connection.close(); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 
+0

更詳細地描述「滯後」。建立初始連接只有很大的延遲嗎?每個查詢花費的時間比預期的多嗎?查詢是否在HostGator的服務器內以正常速度加載? –

回答

1

有幾件事情可以做,以加快您的queri ES延遲:

  • 如果您的應用查詢集約利用持久連接並保持打開,而不是打開每個需要訪問數據庫時,一個新的連接。

  • 在本地運行MySQL服務器以加快連接時間。

  • 爲您的表格的搜索字段(例如playerplayer_data)建立索引以使搜索運行更快。

  • 使用SSD驅動器和大量RAM在強大的專用計算機上運行MySQL服務器,並在my.cnf(工作線程,最大進程,最大連接數,內存限制,緩衝區大小)上設置適當的參數。使用該RAM和處理能力並加快搜索和處理時間。諸如this question and answers之類的東西可能會幫助你處理內存設置,但你可以做的最好的是你自己的,詳盡的在線研究和測試。做你的作業!

  • 使用某種緩存系統來加速閱讀(如memcached)。

  • 如果您的應用程序是數據密集型的並且必須支持大量連接,請獲得更高的帶寬,或者考慮設置羣集來平衡負載。

  • 減少查詢次數!您不需要查詢數據庫兩次以提高級別!

嘗試:

if (playerDataContainsPlayer(p)){ 

    PreparedStatement levelUpdate = connection.prepareStatement(
     "UPDATE player_data SET level=level+1 WHERE player=?;" 
    ); 
    levelUpdate.setString(1, p.getName()); 
    levelUpdate.executeUpdate(); 
    levelUpdate.close(); 
    sql.close(); 

} else { 
    ... 
} 
+1

+1。另請注意,InnoDB引擎比MyISAM處理併發事務_much_更好。 (通過MyISAM,DML語句將阻止對錶的其他訪問,包括SELECT。) – spencer7593

+1

您是對的。我只是想將其添加到我的答案中,以及在使用InnoDB時在單個事務中運行多個查詢的機會。無論如何,InnoDB是5.5以來的默認存儲引擎,所以我猜他可能已經在使用它了... – NotGaeL

+0

你是絕對正確的。我只是提到完整性。就MySQL的性能而言,我同意由於低效的查詢執行計劃(即沒有合適的索引)而執行不必要的查詢(額外的往返)和錯誤的查詢性能,以及連接攪動和網絡延遲是必須的罪魁禍首。 – spencer7593

1

聽起來你正在運行在主服務器線程查詢。如果你的SQL服務器不在本地機器上,你真的不應該這樣做。

有一個read of the tutorial關於如何在後臺運行更多CPU或更長時間運行的任務以避免此類性能損失。

你需要做的是把你的代碼放到一個BukkitRunnable

public class ExampleTask extends BukkitRunnable { 

    private final JavaPlugin plugin; 

    public ExampleTask(JavaPlugin plugin) { 
     this.plugin = plugin; 
    } 

    @Override 
    public void run() { 
     // Put your task's code here 
    } 

} 

,然後讓你在自己的線程中運行代碼離開主服務器線程採取遊戲不間斷的護理,打電話給你的任務是這樣的:

BukkitTask task = new ExampleTask(this.plugin).runTask(this.plugin); 

這應該避免你提到的滯後。注意併發性問題,並注意Bukkit的文檔指定在異步任務內不應發生Bukkit API交互。因此,只需在Task中執行查詢和任何驗證/解析,並將結果傳回服務器線程,以便在需要時在遊戲中使用。

相關問題