【发布时间】:2016-02-12 08:23:34
【问题描述】:
我有一个中等大小的数据库(当时 400,000 行),其中包含一个具有以下架构的测量表:
CREATE TABLE `Measurements` (
`timestamp` timestamp,
`timetick` INTEGER,
`Sensor1` REAL,
`Sensor2` REAL,
PRIMARY KEY(timestamp));
随着时间戳增加(时间戳增加不是恒定的,存在间隙和延迟,但时间戳保证是单调的),通常时间戳也会增加,但在某些情况下它会重置为一个小但不可预测的值。我需要找到所有这样的行。我使用了以下查询(灵感来自Finding the difference in rows in query using SQLite):
select r0,r1,a,b,rd,d from
(select M0.rowid as r0,
M1.rowid as r1,
M0.timestamp as a,
M1.timestamp as b,
min(M1.timestamp)-M0.timestamp as rd,
M1.timetick-M0.timetick as d
from Measurements M0,Measurements M1
where M1.timestamp>M0.timestamp group by M0.timestamp
) where d<0;
这可行,但需要几个小时,而 python 中的相同工作在 30 秒内完成。然而,这是一项非常常见的任务,科学家一直在计算衍生品,而金融专业人士则在计算价格差异。应该有一种有效的方法来做到这一点。
感谢您的帮助和 cmets。
【问题讨论】:
-
显示EXPLAIN QUERY PLAN的输出。
-
@cl 0|0|0|SCAN TABLE Measurements AS M0 USING INDEX sqlite_autoindex_Measurements_1 (~1000000 行) 0|1|1|SEARCH TABLE Measurements AS M1 USING INDEX sqlite_autoindex_Measurements_1 (timestamp>?) (~ 250000 行)
-
在 SQL 中,您可以使用
LAG来查看以前的记录。 SQLite 虽然没有这个分析功能。这意味着它无法处理排序列表并轻松比较相邻行。这是可能的,但会涉及带有大量中间结果的连接,因此对于 DBMS 来说是一项艰苦的工作。因此,您最好使用编程语言(正如您已经注意到的那样)。 -
@Thorsten Kettner:虽然在我的例子中@CL 提供了一个有效的查询,但在尝试理解它时,我注意到细微的变化会创建数据库引擎无法优化的查询,因此执行时间很长.所以我完全同意你的观点,最好坚持使用我更熟悉的语言。