Java JDBC在多线程上优化MySql请求

Java JDBC在多线程上优化MySql请求,java,mysql,multithreading,jdbc,Java,Mysql,Multithreading,Jdbc,我正在构建一个webcrawler,我正在寻找处理我的请求以及线程和数据库(MySql)之间的连接的最佳方法 我有两种类型的线程: 抓取者:他们抓取网站。它们生成url并将其添加到两个表中:表url和表文件。他们从表中选择url 继续爬行。并更新表_url,使其在 我读过一个网址。或在他们阅读时访问=-1。他们可以 删除行 下载者:他们下载文件。它们从表_文件中选择。他们更新表_文件以更改下载的列。他们从来没有 插入任何内容 现在我正在处理这个问题: 我有一个基于的连接池。 每个目标(网站)都有

我正在构建一个webcrawler,我正在寻找处理我的请求以及线程和数据库(MySql)之间的连接的最佳方法

我有两种类型的线程:

  • 抓取者:他们抓取网站。它们生成url并将其添加到两个表中:表url和表文件。他们从表中选择url 继续爬行。并更新表_url,使其在 我读过一个网址。或在他们阅读时访问=-1。他们可以 删除行
  • 下载者:他们下载文件。它们从表_文件中选择。他们更新表_文件以更改下载的列。他们从来没有 插入任何内容
  • 现在我正在处理这个问题: 我有一个基于的连接池。 每个目标(网站)都有以下变量:

    private Connection connection_downloader;
    private Connection connection_fetcher;
    
    private Statement statement;
    private ResultSet resultSet;
    
    当我实例化一个网站时,我只创建两个连接一次。然后,每个线程将根据它们的目标使用这些连接

    每个线程都有这些变量:

    private Connection connection_downloader;
    private Connection connection_fetcher;
    
    private Statement statement;
    private ResultSet resultSet;
    
    在每次查询之前,我都会打开一个SqlStatement:

    public static Statement openSqlStatement(Connection connection){
        try {
            return connection.createStatement();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    每次查询后,我都会使用以下命令关闭sql语句和结果集:

    public static  void closeSqlStatement(ResultSet resultSet, Statement statement){
        if (resultSet != null) try { resultSet.close(); } catch (SQLException e) {e.printStackTrace();}
        if (statement != null) try { statement.close(); } catch (SQLException e) {e.printStackTrace();}
    }
    
    现在,我的Select查询只适用于一个Select(我现在不必选择多个Select,但这很快就会改变),其定义如下:

    public static  String sqlSelect(String Query, Connection connection, Statement statement, ResultSet resultSet){
        String result = null;
        try {
            resultSet = statement.executeQuery(Query);
            resultSet.next();
            result = resultSet.toString();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeSqlStatement(resultSet, statement);
        return result;
    }
    
    和插入、删除和更新查询使用此功能:

    public static int sqlExec(String Query, Connection connection, Statement statement){
        int ResultSet = -1;
        try {
            ResultSet = statement.executeUpdate(Query);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeSqlStatement(resultSet, statement);
        return ResultSet;
    }
    

    我的问题很简单:这能改进得更快吗?我还担心互斥问题,以防止一个线程在另一个线程更新链接时更新链接。

    我看不到在webcrawler线程中包含所有数据库内容的真正优势


    为什么不将静态类与sqlSelect和sqlExec方法一起使用,但不使用Connection和ResultSet参数呢。这两个连接对象也是静态的。在使用连接对象之前,请确保它们是有效的。

    我认为您的设计有缺陷。为一个网站分配一个全职连接将严重限制您的总体工作量

    由于您已经设置了一个连接池,所以在使用之前获取(然后返回)是完全可以的

    同样,
    尝试使用catch
    关闭所有
    结果集和
    语句之后的
    语句将使代码更具可读性,并且使用
    PreparedStatement
    代替
    语句也不会有什么坏处

    一个示例(使用静态dataSource()调用访问池):


    按照相同的模式,我建议您为应用程序使用的所有不同的Insert/Update/select创建方法——所有这些方法都只在DB逻辑中的短时间内使用连接

    你的意思是,总是要求一个新的连接比使用一个已经存在的连接更好吗?这不是更慢吗?你使用一个连接池——所以这不是一个真正的“新”连接,而是一个“回收”的连接。因此,您可以在许多对象之间共享少量的连接。我使用了一个连接池,认为这样会更好,因为我正在构建一个多线程应用程序。我说得对吗?它安全吗(为了数据完整性?)是的,连接池很好。关于数据完整性:考虑一下在onw事务中需要做什么,然后将所有代码放在一个连接中。还有一件事:我永远不必关闭连接?只是结果集和语句?