【问题标题】:Optimization reading from database从数据库读取优化
【发布时间】:2020-11-20 05:14:18
【问题描述】:

我需要检查数据库是否存在约 2k 条记录,我在 db 大小 1.000.000 上测试 id,它需要 46 秒。它太长了,因为将来这个数据库可以有超过 500.000.000 条记录。有什么方法可以加快从 db 搜索的速度吗?我在 java 中使用 JDBC,代码如下:

public int search(List<String> toSearch) throws SQLException {
    String query = "SELECT * FROM strings where string =  ?";
    StringBuilder sB = new StringBuilder(query);
    for (int i=0; i<toSearch.size()-1; i++) {
        sB.append("OR string=?");
    }
    System.out.println(toSearch.size());

    PreparedStatement prep = con.prepareStatement(sB.toString());
    
    int i=1;
    for (String string : toSearch) {
        prep.setString(i, string);
        i++;
    }
    long data = System.currentTimeMillis();
    ResultSet resultSet = prep.executeQuery();
    long data2 = System.currentTimeMillis();
    System.out.println((data2 - data) / 1000);
    List<String> toReturn = new ArrayList<>();
    while (resultSet.next()) {

        toReturn.add(resultSet.getString("string"));

    }
    return toReturn.size();

}

表名是字符串,列是字符串。

【问题讨论】:

  • 你想继续使用 h2 吗?对于大量数据,这不是一个好的选择。尝试 MySQL,然后在 db 本身中有一个过程
  • SQL 查询长度有一些限制。例如,尝试通过使用一批 100 个元素来解决这个问题。在这种情况下,您甚至可以引入多个线程来读取数据库。
  • 想象一下你有桌子strings。现在将ids 插入一个新的临时表并尝试加入两个表。
  • 最好尝试 Postgres 而不是 MySQL
  • 并执行SELECT string FROM strings ...,因为较小的 ResultSet 也更快。

标签: java sql database jdbc h2


【解决方案1】:

首先,您需要在string 列上有一个索引。

CREATE INDEX indexName ON strings(string);

不要为 H2 构造带有可变数量参数的查询。使用

PreparedStatement ps = con.prepareStatement("SELECT * FROM strings WHERE string = ANY(?)");
ps.setObject(1, toSearch.toArray(new String[0]));

如果您使用一些不受支持的旧 H2 版本,请改用其 TABLE() 函数,如随您的版本分发的文档中所述(PDF 中的Prepared Statements and IN(...) 部分)。

对于其他 DBMS,您可能需要其他技巧来避免动态生成 SQL 代码,= ANY(?) 可以在 PostgreSQL 及其分支和 H2 中工作,但不能在其他 DBMS 中。

【讨论】:

    猜你喜欢
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    相关资源
    最近更新 更多