Java 在SQLite数据库中逐数组存储
在我的Java应用程序中,我需要在硬盘上存储一个大表,因为我希望它是持久的 我的第一次尝试是这样的: (i&j可以爬升到300000或更多,因此我有一个300000^2个双条目的数组,这会使我的系统崩溃。)Java 在SQLite数据库中逐数组存储,java,arrays,database,performance,sqlite,Java,Arrays,Database,Performance,Sqlite,在我的Java应用程序中,我需要在硬盘上存储一个大表,因为我希望它是持久的 我的第一次尝试是这样的: (i&j可以爬升到300000或更多,因此我有一个300000^2个双条目的数组,这会使我的系统崩溃。) stmt.executeUpdate(“如果存在计算,则删除表;”); stmt.executeUpdate(“创建表计算(factorA,factorB,result);”; 双温=0; 对于(i=0;i
stmt.executeUpdate(“如果存在计算,则删除表;”);
stmt.executeUpdate(“创建表计算(factorA,factorB,result);”;
双温=0;
对于(i=0;i
现在,这执行起来非常慢,可能是因为SQL命令是一个字符串等等
我的新猜测是,首先计算10.000个i的结果,然后将它们作为一个单位存储到数据库中可能更好
但在我尝试实施之前,有人有更好的想法吗?数据库使用不是强制性的,只是一种易于访问和快速实现的方法。尝试在一个
事务中添加每个n
左右的行(假设失败不是问题,例如,如果某些行插入失败,您可以继续而不回滚以前的行)。
在循环中声明一个计数器:
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++
(别忘了在外部循环中重新打开事务)
int BLOCK\u SIZE=15000;
stmt.executeUpdate(“删除表格,如果存在计算;”);
stmt.executeUpdate(“创建表计算(factor_idx text NOT NULL主键,result text NOT NULL);”;
双温=0;
int block_ctr=1;
StringBuilder sb=新的StringBuilder();
for(int i=0;i 如果(block_ctr确保将批量插入作为事务处理;-这将在SQLite引擎中对它们进行排队,然后当您指示事务已完成时,将以闪电般的速度提交它们,而不是逐个提交。您需要快速写入还是快速读取?您将提取多少行?factorA+factorB的组成是什么可用作索引?实际上我需要两者,快速书写和阅读,但在第一次写作时。好的,我使用“PreparedStatement”现在,这似乎表现得很好。谢谢,这实际上就是我现在正在做的。但是,阅读速度还是很慢。我只是认为,当你需要访问非常大的表时,SQLite不是一种方式。但是还有什么呢?你的查询速度慢吗?试着直接在Sql IDE中运行吗?试着分页,每隔几行读/写一行,就是这样emory effective.搞笑的是,当我得到>1时,这就停止了…嗯,我需要弄清楚,为什么会发生这种情况。当我将块大小减少到500时,我得到:[SQLITE\u ERROR]SQL错误或缺少数据库(复合选择中的术语太多).当我使用100表示块大小时,它的执行速度更快,但不如preparedstatement:-DI不知道复合选择中术语的限制…我想我学到了一些东西:)我认为我对单个索引列的快速读取的想法比同时选择I和j更有效。使用preparedStatement和我提出的表结构。使用8000x8000进行I和j读取效果非常好!这是我的方法…非常感谢!
if(count % n == 0){
//commit the transaction
}
count++
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++;
}
}
}