【问题标题】:MySQL lag on get (SELECT)MySQL 延迟获取 (SELECT)
【发布时间】:2018-01-20 18:18:49
【问题描述】:

我的问题是get级别有update troo所以服务器开始滞后70% tps loss我不知道如何优化它?

public static int getCoins(Player player) {
    try {
        PreparedStatement q = Main.sql.prepareStatement("SELECT Coins FROM Players WHERE Players_UUID = ?");
        q.setString(1, player.getUniqueId().toString());

        int coins= 0;
        ResultSet rs = q.executeQuery();

        while(rs.next()){
            balance = rs.getInt("Coins");
        }

        q.close();

        return coins;

    } catch (SQLException e) {
        e.printStackTrace();
    }

    return 0;
}

【问题讨论】:

标签: java mysql jdbc


【解决方案1】:

您不需要每次都进行sql查询来获取硬币,只需使用数据创建一个int或hashmap字段并每隔X次检查一次数据是否已更改。

如果它已更改,则将更新发送到 mysql 服务器并标记该数据已保存,如两个 hashmap/int 字段。

hashmap1 = 数据库数据 hashmap2 = 服务器数据

如果 hashmap1 和 hashmap2 相同,则不要更新。

在 schedulerAsync 或 thread 等异步函数中进行更新。

这里有一个类似的例子:

package test;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

import com.mysql.jdbc.Connection;

public class Event extends JavaPlugin implements Listener {

    // Mysql update data
    public static ConcurrentHashMap<UUID, Integer> player_zombiekills = new ConcurrentHashMap<UUID, Integer>();

    // Mysql connection data
    public static Connection connection;
    private String host = "localhost";
    private String database = "DB";
    private String username = "user";
    private String password = "123";
    private int port = 3306;

    //Kill zombie event
    @EventHandler
    public void zombieDeath(EntityDeathEvent eve) {
        if (!(eve.getEntity() instanceof Zombie)) return; // Stop if death is not zombie
        if (!(eve.getEntity().getKiller() instanceof Player)) return; // Stop if killer is not player
        UUID uid = eve.getEntity().getKiller().getUniqueId(); // Save player uuid
        if (player_zombiekills.contains(uid)) player_zombiekills.put(uid, 0); // Set kills 0 if not exist in hashmap
        player_zombiekills.put(uid, player_zombiekills.get(uid) + 1); // plus 1 kills value
    }

    //On enable connection
    public void onEnable() {
        try {
            if (connection != null && !connection.isClosed()) return;
            Class.forName("com.mysql.jdbc.Driver");
            connection = (Connection) DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, username, password);
            if (!connection.isClosed()) System.out.println("[MySQL] " + "Connected to '" + database + "'");
        } catch (Exception e) {
            System.err.println("[MySQL] " + e.getMessage());
        }

        new BukkitRunnable() {
            public void run() {
                // for updates
                for (Entry<UUID, Integer> ent : player_zombiekills.entrySet()) {
                    try {
                        // send update
                        connection.createStatement().executeUpdate("UPDATE `tablename` SET `zombiekills`=`zombiekills`+" + ent.getValue() + " WHERE `uuid`='" + ent.getKey().toString() + "'");
                        // Sucess remove entry from hashmap to reset kills
                        player_zombiekills.remove(ent.getKey());
                    } catch (SQLException e) { // If error
                        System.err.println("[MySQL] " + e.getMessage()); // Print error in console
                    }
                }
            }
        }.runTaskTimerAsynchronously(this, 20, 20 * 60 * 10); // Run async loop every 10 minutes
    }
}

【讨论】:

    【解决方案2】:

    我不知道该怎么做,因为如果您更改 BDD 中的数据,它不会在服务器上更改,因此如果我不是每 1 秒获取一次,它将无法正常工作,因此我已经使用异步进行了优化,但是如果不返回到拿硬币……

    【讨论】:

    • 在 PlayerJoinEvent 上将播放器添加到列表中,例如“pending_get_list”,然后在下一个异步任务中执行 mysql 选择并在任何字段中保存数据。如果修改添加到另一个列表,如“pending_sync_list”,并在下一个异步任务中执行 mysql 更新。
    • 可以举个例子吗?
    猜你喜欢
    • 1970-01-01
    • 2021-12-03
    • 2022-01-23
    • 1970-01-01
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多