首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对MySQL间歇性java慢查询

对MySQL间歇性java慢查询
EN

Stack Overflow用户
提问于 2014-10-22 00:38:44
回答 2查看 804关注 0票数 3

在我用JAVA编写的应用服务器中,我出现了以下症状:

每小时一到两次,对MySQL的查询非常慢(8-10秒/查询)。

我的服务器查询两个不同的数据库服务器,它们都有这种症状,但不是同时出现。

为了消除网络故障,我运行了一个网络监视器,它报告应用程序服务器和数据库服务器之间的网络状态良好。而且,我的应用服务器有4个线程,只有1个线程查询速度慢,其他3个线程查询正常。

在两个数据库服务器上,我将连接超时设置为10s,有些查询超时(>10s),有些查询没有超时但速度很慢(查询时间超过1s,通常是8s-9s)。

1奇怪的是,尽管客户端有慢查询,但数据库服务器端没有慢查询日志(我配置的慢查询时间是1秒)。

下面是我用来连接数据库的一段代码:

代码语言:javascript
运行
复制
    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;
}
EN

回答 2

Stack Overflow用户

发布于 2014-10-24 17:46:46

您没有使用连接池,所以java服务器将保持与mysql的连接和断开。表中有很多行吗?有没有其他线程会继续插入?

票数 1
EN

Stack Overflow用户

发布于 2014-10-24 18:02:12

我强烈建议使用合适的JDBC Connection Pool而不是DriverManager,后者的缺点是每次需要时都会创建一个新的连接,没有池。创建与数据库的连接通常是一项冗长的操作。

接下来,你的代码是有缺陷的,imho,你的连接仍然是打开的,以防出现异常,你应该关闭ResultSetPreparedStatement以及连接。最好是在finally块中。

我建议重写代码如下。

代码语言:javascript
运行
复制
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);
}

理想情况下,您应该设置DataSource并使用它来获取连接,而不是设置dbConfigString

代码语言:javascript
运行
复制
public void setDataSource(DataSource ds) {
    this.ds=ds;
}

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

这样,您就可以注入适当的连接池,如Commons DBCPHikariCP

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26491815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档