5

我有一个 Java 程序需要遍历 aHashMap以获取一个参数,然后用于查询 MySQL 数据库。

代码如下:

Iterator<Entry<String, Double>>it = ws.entrySet().iterator();
Connection con = null;

while(it.hasNext())  
{
    Entry<String, Double>pairs = it.next();
    PreparedStatement ps = con.prepareStatement("select doc_freq from lookup where word=?");
    ps.setString(1, pairs.getKey());
    ResultSet rs = ps.executeQuery();
}

为循环的每次迭代(大约 500 次)重复访问数据库的过程正在减慢我的应用程序的速度。有什么方法可以一次发送所有这些参数,以便我只访问一次数据库?

4

3 回答 3

1

考虑到 ws 是一个地图,您可以这样进行单个查询:

Connection con = getConnection();
Set<String> ks = ws.keySet();

if (ks.size() > 0) {
    StringBuilder inStatement = new StringBuilder("?");
    for (int i = 1; i < ks.size(); i++) {
        inStatement.append(", ?");
    }

    PreparedStatement ps = con.prepareStatement("select doc_freq from lookup where word in (" + inStatement.toString() + ")");

    int k = 1;
    for (String key : keySet) {
        ps.setString(k++, key);
    }
    ResultSet rs = ps.executeQuery();
}
于 2013-04-05T19:29:44.373 回答
0

准备语句一次然后迭代并为其设置参数然后执行。这是来自 javadoc

带或不带 IN 参数的 SQL 语句可以预编译并存储在PreparedStatement对象中。然后可以使用该对象多次有效地执行该语句。此方法针对处理受益于预编译的参数化 SQL 语句进行了优化。如果驱动支持预编译...

Iterator<Entry<String, Double>>it = ws.entrySet().iterator();
Connection con = getConnection();

PreparedStatement ps = con.prepareStatement("select doc_freq from lookup where word=?");
while(it.hasNext())  
{
    Entry<String, Double>pairs = it.next();
    ps.setString(1, pairs.getKey());
    ResultSet rs = ps.executeQuery();
}

当查询编译到数据库时,它可以更快地执行和逐一检索结果,这与执行一个带有多个参数的查询相同。性能是平等的。

但是,如果您准备好,编译相同的 SQL 查询多种类型,那么每次编译查询时,数据库都会创建执行计划,这很不合时宜。

这就是为什么这种技术在文档中称为高效的原因。该术语也称为解释计划,它由数据库创建以更好地优化查询。

于 2013-04-05T19:20:44.123 回答
0

从问题中不清楚为什么它很慢,但一个常见的问题是每笔交易的开销。

您可以将innodb_flush_log_at_trx_commit设置为 0 或 2,一切都会更快。请注意,默认值 1 是唯一符合 ACID 的设置。对于大多数设置,2 是一个非常好的值。

set global innodb_flush_log_at_trx_commit = 2;
于 2013-04-05T19:27:34.893 回答