在SQLite-Database中按数组存储数组

时间:2014-01-12 16:05:11

标签: java arrays database performance sqlite

在我的Java应用程序中,我需要在硬盘上存储一个大表,因为我希望它是持久的。

我的第一次尝试是这样的: (i& j可以爬到300.000甚至更多,所以我有一个300.000 ^ 2的双重数据,这会导致我的系统崩溃。)

stmt.executeUpdate("DROP TABLE IF EXISTS calculations;");
stmt.executeUpdate("CREATE TABLE calculations (factorA, factorB, result);");
double temp = 0;
for (i = 0; i < datasource.size(); i++) {
    for (int j = 0; j < datasource.size(); j++) {
        if (i != j) {
            temp = calc(datasource.get(i),datasource.get(j));
            stmt.execute("INSERT INTO calculations (factorA, factorB, result) VALUES ('"+i+"','"+j+"','"+temp+"')");
        }
    }
}

现在,这执行速度极慢,可能是因为SQL命令是一个字符串等。

我的新猜测是,首先计算结果,即10.000 i,然后将它们作为一个单元存储到数据库中可能会更好。

但在我尝试实施之前,是否有人有更好的想法?数据库使用不是强制性的,只需轻松访问并快速实施。

2 个答案:

答案 0 :(得分:1)

尝试在n内添加每个Transaction左右的行(假设失败不是问题,例如,如果某些行无法插入,则可以继续而不回滚之前的行)。 在循环中声明一个反ous:

int n = 1000; //commit every 1000 rows, or you can tweak
int count = 0; //counter for rows inserted

在外部循环中启动事务。增加并检查内循环中的计数器

if(count % n == 0){
  //commit the transaction
}
count++

(别忘了在外循环中再次重新打开Transaction)

http://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html

答案 1 :(得分:1)

        int BLOCK_SIZE = 15000;
        stmt.executeUpdate("DROP TABLE IF EXISTS calculations;");
        stmt.executeUpdate("CREATE TABLE calculations (factor_idx text NOT NULL PRIMARY KEY,result text NOT NULL);");
        double temp = 0;
        int block_ctr = 1;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < datasource.size; i++) {
            for (int j = 0; j < datasource.size; j++) {
                if (i != j) {
                    temp = calc(a, b);
                    // init the statement when counter = 1
                    if (block_ctr == 1) {
                        sb.append("INSERT INTO 'calculations' SELECT '" + i + "_" + j + "' AS 'factor_idx', '" + temp + "' AS 'result'");
                    }


                    // then commit only every BLOCK_SIZE blocks
                    if (block_ctr <= BLOCK_SIZE) {
                        sb.append("UNION SELECT '" + i + "_" + j + "','" + temp + "'");
                    } else {
                        stmt.execute(sb.toString());
                        sb.setLength(0); // better then creating a new sb 
                        block_ctr = 0;
                    }
                    block_ctr++;
                }
            }
        }

我减少了列数,并使用StringBuilder创建了一个组合语句。它应该快得多,允许使用您创建连接i和j的主键列上的索引更快地读取。试着让我知道,我很好奇:)