SELECT总计(值)的SQLite和性能问题

时间:2014-01-07 10:05:50

标签: java sql database sqlite

你好,新年快乐,

我们仍在努力应对我们的模拟应用。特别是在运行时使用SQLite作为模拟数据的“实时”查找表。

首先让我告诉你桌面设计: SQLfiddle - Link

在这里,你可以看到一个表'testtable':

  1. 'id'(整数):作为主键
  2. 'time_abs'(整数):表示与模拟时钟相关联的时间戳
  3. 'r_m'(double):代表某种流量的“质量率”(单位为kg / s,例如)
  4. 'T_r'(double):代表'质量流量的温度'
  5. 'type'(varchar):代表质量流量的种类(例如水)
  6. 'x0'(varchar):表示质量流量(例如容器#1)的偏离
  7. 'x1'(varchar):表示质量流量的目的地(例如,容器#2)
  8. (实际上这个表中还有一些化学和物理属性)

    模拟创建这些数据,并使用Java方法将其写入数据库,这非常有效(可能有几个10k / s)。

    问题是:

    模拟运行时,模拟引擎有时会需要某些信息 “ 14号船只1的总质量是多少? ” 我们通过以下查询收到此信息:


    SELECT total(r_m) FROM testtable WHERE time_abs<=14 AND x1='vessel2') - (SELECT total(r_m) FROM testtable WHERE time_abs<=14 AND x0='vessel2'); 这是:在一个本地点添加所有收入率并减去所有结果率


    一开始就可以正常工作。但最终我们在这个表中有大约800万到1000万行,性能下降很多。例如。这个查询几乎需要6秒(在firefox中使用SQLite漫游器需要3-4秒)。

    同样最后我们想用1000个时间单位(time_abs)绘制总质量,这个查询需要大约1000 * 6秒。显然很多。

    所以问题是,我们可以做些什么来显着提高性能?

3 个答案:

答案 0 :(得分:1)

如果您使用一个或多个其他字段,可以帮助您更新/增加所需值

eg. total_rm  or total_diff

然后您不需要total(),但可以直接使用

访问该值
SELECT total_rm FROM testtable WHERE time_abs=14 AND x1='vessel2')   

当然你应该在time_abs上创建一个索引。

答案 1 :(得分:1)

的可能性:

  1. 预先计算您的所需结果。因此,当您执行原始数据插入时,请更新“总计”表中的行。每行模拟您的查询,根据time_abs和vessel进行更新。所以表可能有列:

    time_abs,vessel,running_total

    您使用基于time_abs和vessel

  2. 的新值更新running_total
  3. 将原始数据处理卸载到功能更强大的服务器。因此,在每个n个原始数据插入上,使用Web服务将该数据上载到功能更强的服务器。让那台机器实时计算你的结果。一旦数据插入完成(数据收集结束),理论上您的结果就可以返回到Android(再次通过Web服务或类似方式)。

答案 2 :(得分:1)

使用以下索引可以提高此特定查询的效率:

CREATE INDEX i_ir ON testtable(x1, time_abs, r_m);
CREATE INDEX i_or ON testtable(x0, time_abs, r_m);