2014-06-17 52 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中执行查询和任何验证/解析,并将结果传回服务器线程,以便在需要时在游戏中使用。

相关问题