2016-02-12 85 views
0

我有一个中等大小的数据库(当时40万行)包含具有以下模式的测量表:sqlite3的如何计算差分改变

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; 

这工作,但需要时间,而在30秒结束蟒同样的工作。然而,这是一个非常普遍的任务,科学家一直在计算衍生工具,而财务专业人员则计算价格差异。应该有一个有效的方法来做到这一点。
我会感谢您的帮助和意见。

+0

显示[EXPLAIN QUERY PLAN](http://www.sqlite.org/eqp.html)的输出。 –

+0

@cl 0 | 0 | 0 | SCAN TABLE测量AS M0使用索引sqlite_autoindex_Measurements_1(〜1000000行) 0 | 1 | 1 | SEARCH TABLE测量AS M1使用索引sqlite_autoindex_Measurements_1(timestamp>?)(〜250000 rows) – NameOfTheRose

+1

SQL你可以使用'LAG'来查看以前的记录。但SQLite不具有这个分析功能。这意味着它无法在分类列表上工作并轻松比较相邻行。这是可能的,但会涉及具有较大中间结果的连接,因此对于DBMS来说是艰苦的工作。因此,您最好使用编程语言(如您已经注意到的)。 –

回答

1

与GROUP BY的连接很难优化。

更好地利用相关子查询找到相应的下一行:

SELECT m0.rowid AS r0, 
     m1.rowid AS rn, 
     m0.timestamp AS a, 
     m1.timestamp AS b, 
     m1.timestamp - m0.timestamp AS rd, 
     m1.timetick - m0.timetick AS d 
FROM (SELECT rowid,  -- This is the core query attaching to each row 
      timestamp, -- the rowid of its next 
      timetick, 
      (SELECT rowid 
       FROM measurements 
       WHERE timestamp > m.timestamp 
       ORDER BY timestamp 
       LIMIT 1 
      ) AS r1 
     FROM Measurements AS m 
    ) AS m0 
JOIN measurements AS m1 ON m0.r1 = m1.rowid 
WHERE m1.timetick - m0.timetick < 0; 

如果时间戳是一个整数,使该列中的INTEGER PRIMARY KEY,以避免额外的索引查找。

+0

谢谢,时间戳不是整数。此查询速度非常快,但不会产生正确的结果,可能是因为rowid升序的行不总是具有增加的时间戳 - 测量值会收集到不同的计算机中并进行合并。我不希望在每次添加测量值时将整个表格复制到新表格中,以确保增加的rowid意味着增加时间戳(除非我必须或可能会在python中执行此操作) – NameOfTheRose

+0

编辑问题以显示一些示例数据并期望的结果。 –

+0

我觉得我需要包括所有的数据来显示问题,我可以做到这一点(他们是室温测量),但数据库是40MB。只有14例,其中timetick重置 – NameOfTheRose