jdbc 向表中插入速度慢(准备好的语句)

jdbc slow insertion into tables (Prepared Statements)

这是我的第一个问题,所以当我问错问题时请不要惊慌失措;)

我是 运行 一个 Minecraft 服务器网络,我使用 spigot,它是服务器软件。 这运行在 linux 16GB 和 Intel Xeon 的根服务器上。

对于 Spigot,您可以简单地使用 API 编写插件代码。没问题,因为 API 非常简单。

我的问题: 我做了一个统计系统,你可以使用mysql在不同的服务器上看到你的统计数据,所以它们在每个服务器上都是一样的。 带有此 mysql 插件的服务器性能不佳,我真的认为它来自 MySQL。 服务器的 TPS(每秒滴答数)为 18-19,理想情况下应为 20 才能无滞后。 我使用了准备好的语句。

这是我的 MySQL class:

package Heroz.FFA.MySQL;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MySQL {
        private String HOST = "";
        private String DATABASE = "";
        private String USER = "";
        private String PASSWORD = "";
        private String TABLE = "";
        public static Connection con;

        public MySQL(String host, String database, String user, String password,
                        String table) {
                this.TABLE = table;
                this.HOST = host;
                this.DATABASE = database;
                this.USER = user;
                this.PASSWORD = password;
                startConnection();
        }

        public void startConnection() {
                try {
                        try {
                                Class.forName("com.mysql.jdbc.Driver");
                        } catch (ClassNotFoundException e) {
                                e.printStackTrace();
                        }
                        con = DriverManager.getConnection("jdbc:mysql://" + this.HOST
                                        + ":3306/" + this.DATABASE, this.USER, this.PASSWORD);
                        System.out.println("MySQL Verbindung wurde hergestellt!");
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }

        public void stopConnection() {
                try {
                        if (con != null) {
                                con.close();
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }

        public void update(String name) {
                try {
                        PreparedStatement st = con.prepareStatement(name);
                        st.executeUpdate(name);
                        st.close();
                } catch (SQLException e) {
                        startConnection();
                        e.printStackTrace();
                }
        }

        public static boolean exists(String Spielername) {
                try {
                        PreparedStatement st = con
                                        .prepareStatement("SELECT * FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = st.executeQuery();
                        if (rs.next()) {
                                return rs.getString("Spielername") != null;
                        }
                        return false;
                } catch (SQLException e) {
                        e.printStackTrace();
                }
                return false;
        }

        public static int getKills(String Spielername) {
                int kills = 0;
                try {
                        PreparedStatement st = con
                                        .prepareStatement("SELECT Kills FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = st.executeQuery();
                        if (rs.next()) {
                                kills = rs.getInt("Kills");
                        } else {
                                kills = 0;
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
                return kills;
        }

        public static int getTode(String Spielername) {
                int tode = 0;
                try {
                        PreparedStatement st = con
                                        .prepareStatement("SELECT Tode FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = st.executeQuery();
                        if (rs.next()) {
                                tode = rs.getInt("Tode");
                        } else {
                                tode = 0;
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
                return tode;
        }

        public static void createPlayer(String Spielername) {
                try {
                        PreparedStatement x = con
                                        .prepareStatement("SELECT * FROM FFA WHERE Spielername = '"
                                                        + Spielername + "';");
                        ResultSet rs = x.executeQuery();
                        if (!rs.next()) {
                                x.executeUpdate("INSERT INTO FFA(Spielername, Kills, Tode, Wins, Punkte, Gespielt) VALUES ('"
                                                + Spielername + "', '0', '0', '0', '0', '0');");
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }

        public static void addTode(String Spielername, int karma) {
                try {
                        PreparedStatement x = con
                                        .prepareStatement("SELECT * FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = x.executeQuery();

                        int punkte = getTode(Spielername) + karma;
                        if (rs.next()) {
                                x.executeUpdate("UPDATE FFA SET Tode = '" + punkte
                                                + "' WHERE Spielername = '" + Spielername + "'");
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }

        public static void addKills(String Spielername, int karma) {
                try {
                        PreparedStatement x = con
                                        .prepareStatement("SELECT * FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = x.executeQuery();

                        int punkte = getKills(Spielername) + karma;
                        if (rs.next()) {
                                x.executeUpdate("UPDATE FFA SET Kills = '" + punkte
                                                + "' WHERE Spielername = '" + Spielername + "'");
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }

        public static int getWins(String Spielername) {
                int wins = 0;
                try {
                        PreparedStatement st = con
                                        .prepareStatement("SELECT Wins FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = st.executeQuery();
                        if (rs.next()) {
                                wins = rs.getInt("Wins");
                        } else {
                                wins = 0;
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
                return wins;
        }

        public static void addWins(String Spielername, int zahl) {
                try {
                        if (exists(Spielername)) {
                                PreparedStatement x = con
                                                .prepareStatement("SELECT * FROM FFA WHERE Spielername = '"
                                                                + Spielername + "'");
                                ResultSet rs = x.executeQuery();

                                int punkte = getWins(Spielername) + zahl;
                                if (rs.next()) {
                                        x.executeUpdate("UPDATE FFA SET Wins = '" + punkte
                                                        + "' WHERE Spielername = '" + Spielername + "'");
                                }
                        } else {
                                System.out.println("§cFehler!");
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }

        public static int getPunkte(String Spielername) {
                int punkte = 0;
                try {
                        PreparedStatement st = con
                                        .prepareStatement("SELECT Punkte FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = st.executeQuery();
                        if (rs.next()) {
                                punkte = rs.getInt("Punkte");
                        } else {
                                punkte = 0;
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
                return punkte;
        }

        public static void addPunkte(String Spielername, int karma) {
                try {
                        PreparedStatement x = con
                                        .prepareStatement("SELECT * FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = x.executeQuery();

                        int punkte = getPunkte(Spielername) + karma;
                        if (rs.next()) {
                                x.executeUpdate("UPDATE FFA SET Punkte = '" + punkte
                                                + "' WHERE Spielername = '" + Spielername + "'");
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }

        public static int getPlayed(String Spielername) {
                int gespielt = 0;
                try {
                        PreparedStatement st = con
                                        .prepareStatement("SELECT Gespielt FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = st.executeQuery();
                        if (rs.next()) {
                                gespielt = rs.getInt("Gespielt");
                        } else {
                                gespielt = 0;
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
                return gespielt;
        }

        public static void addPlayed(String Spielername, int karma) {
                try {
                        PreparedStatement x = con
                                        .prepareStatement("SELECT * FROM FFA WHERE Spielername = '"
                                                        + Spielername + "'");
                        ResultSet rs = x.executeQuery();

                        int punkte = getPlayed(Spielername) + karma;
                        if (rs.next()) {
                                x.executeUpdate("UPDATE FFA SET Gespielt = '" + punkte
                                                + "' WHERE Spielername = '" + Spielername + "'");
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }
}

如何解决这些性能问题? 每 1-10 秒一个 Player dies/kills 某人,因此它必须更新 table.

如果您对内容的动态部分使用绑定变量,则使用 PreparedStatement 只会提高性能。

例如:

PreparedStatement x = con.prepareStatement("SELECT * FROM FFA WHERE Spielername = 
'"+ Spielername + "';");

应改为:

PreparedStatement x = con.prepareStatement("SELECT * FROM FFA WHERE Spielername = ?;");
x.setString(1, Spielername);

您当前对 PreparedStatements 的使用实际上可能比直接执行您的语句要慢。

此外,您的更新也应该使用 PreparedStatements。这是另一个例子:

x.executeUpdate("UPDATE FFA SET Tode = '" + punkte
                 + "' WHERE Spielername = '" + Spielername + "'");

应改为:

PreparedStatment pStmt = conn.prepareStatement("UPDATE FFA SET Tode = ?"
    + " WHERE Spielername = ?");
pStmt.setString(1, punkte);
pStmt.setString(2, Spielername);
pStmt.executeUpdate();