我可以使用data.tables加快R和Sqlite之间的计算速度吗?

时间:2019-07-03 17:55:11

标签: r sqlite data.table

我有一个约140万行和16列的sqlite数据库。

我必须对80,000个id进行操作:

  1. 获取与该ID相关联的所有行
  2. 转换为R日期对象并按日期排序
  3. 计算两个最近日期之间的差异

对于每个ID,我一直使用R的dbSendQuery和dbFetch从R查询sqlite,而第2步和第3步是在R中完成的。有没有一种更快的方法?将整个sqlite表加载到data.table中会更快还是更慢?

2 个答案:

答案 0 :(得分:1)

我在很大程度上取决于您如何解决该问题。

正常情况下,将整个查询加载到内存中,然后执行操作会比我在grahics上所见和见过的更快,我现在无法向您显示基准。从逻辑上讲,这很有希望,因为您必须在多个data.frames上重复多次操作。正如您在此处看到的,80k行非常快,比3x 26xxx行要快。

enter image description here

不过,您可以查看parallel软件包,并在计算机上使用多个内核来加载数据子集并并行处理它们,每个子集都在多个内核上。

在这里您可以找到有关如何执行此操作的信息: http://jaehyeon-kim.github.io/2015/03/Parallel-Processing-on-Single-Machine-Part-I

答案 1 :(得分:1)

如果您要在R中进行所有操作,并在一个循环中从数据库中提取行80,000次,那么使用sqlite一次完成所有操作可能会得到更好的结果。

给出如下骨架表:

CREATE TABLE data(id INTEGER, timestamp TEXT);
INSERT INTO data VALUES (1, '2019-07-01'), (1, '2019-06-25'), (1, '2019-06-24'),
                        (2, '2019-04-15'), (2, '2019-04-14');
CREATE INDEX data_idx_id_time ON data(id, timestamp DESC);

查询,例如:

SELECT id
     , julianday(first_ts)
       - julianday((SELECT max(d2.timestamp)
                    FROM data AS d2
                    WHERE d.id = d2.id AND d2.timestamp < d.first_ts)) AS days_difference
FROM (SELECT id, max(timestamp) as first_ts FROM data GROUP BY id) AS d
ORDER BY id;

会给你

id          days_difference
----------  ---------------
1           6.0
2           1.0

现代版本的sqlite(3.25或更高版本)的替代方法(编辑:在具有1600万行和80000个不同ID的测试数据库上,它的运行速度比上述数据库慢得多,因此您不想实际使用它):

WITH cte AS
 (SELECT id, timestamp
       , lead(timestamp, 1) OVER id_by_ts AS next_ts
       , row_number() OVER id_by_ts AS rn
  FROM data
  WINDOW id_by_ts AS (PARTITION BY id ORDER BY timestamp DESC))
SELECT id, julianday(timestamp) - julianday(next_ts) AS days_difference
FROM cte
WHERE rn = 1
ORDER BY id;

(该索引对于这两个版本的性能都是必不可少的。可能要在填充它并创建索引之后的某个时刻在表上运行ANALYZE。)