简体   繁体   中英

intermitten java slow query to MySQL

In my application server, which is written in JAVA, I have the following symptom:

Once or twice per hour, the query to MySQL is extremely slow (8-10s/query).

My server queries to 2 different database servers, and both of them have this symptom, but not at the same time.

To eliminate the cause of network, I run a network monitor, and it reports that the network between application server and database servers is good. Moreover, my app server has 4 threads, only 1 thread have slow query, the other 3 still query well.

On both DB servers, I set connection timeout to 10s, there are some queries which timeout (>10s), some queries not timeout but slow (query time longer than 1s, usually 8s-9s).

1 strange thing is, despite there are slow query on client side, there is no slow query log on database server side (I config slow query time is 1s).

Here is a piece of my code that I'm using to connect to DB:

    public boolean checkSession(String sessionId) {
    Connection conn = null;
    conn = getDBConnection();
    if(conn == null)
        return false;
    try {
        PreparedStatement stm = conn.prepareStatement("SELECT uid FROM sessions WHERE sid=?");
        stm.setString(1, sessionId);
                    ResultSet rs = stm.executeQuery();

        if(rs.next()){
                        if(rs.getInt("uid") == tamtayId){
                            conn.close();
                            return true;
                        }    
        }
        conn.close();
        return false;
    } catch (SQLException e1) {
        e1.printStackTrace();
    }   
    return false;
}
public void setDbConfigString(String str){
    conStr = str;
}
public Connection getDBConnection(){
    Connection conn = null;
    try{
        conn = DriverManager.getConnection(conStr);
    }
    catch (Exception e)  {
        e.printStackTrace();
    }
    return conn;
}

You did not use a connection pool, so the java server will keep connecting and disconnecting mysql. Are there many lines in the table? Is there some other thread will keep inserting?

I would strongly suggest to use a proper JDBC Connection Pool instead of the DriverManager , the drawback of the latter is that it creates a new connection each time one is needed, there is no pooling. Creating a connection with the database is, generally, a lengthy operation.

Next to that your code is flawed, imho, your connection remains open in case of an exception and you should close the ResultSet and PreparedStatement as well as the connection. Preferably in a finally block.

I suggest rewriting the code as follows.

public boolean checkSession(String sessionId) {
    Connection conn = getDBConnection()
    PreparedStatement stm = null;
    ResultSet rs = null;
    boolean val = false;
    try {
        if (conn != null) {
            stm = conn.prepareStatement("SELECT uid FROM sessions WHERE sid=?");
            stm.setString(1, sessionId);
            rs = stm.executeQuery();

            if(rs.next()){
                val = rs.getInt("uid") == tamtayId;
            }
       }
    } catch (SQLException e1) {
        e1.printStackTrace();
    } finally {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {}
        }
        if (stm != null) {
            try {
                stm.close();
            } catch (SQLException e) {}
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {}
        }
    }
    return val;
}

public void setDbConfigString(String str){
    conStr = str;
}

public Connection getDBConnection() throws SQLException {
    return DriverManager.getConnection(conStr);
}

Instead of setting the dbConfigString you should set the DataSource ideally and use that for obtaining connections.

public void setDataSource(DataSource ds) {
    this.ds=ds;
}

public void getDBConnection() throws SQLException {
    return ds.getConnection();
}

That way you can inject a proper connection pool like Commons DBCP or HikariCP .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM