【发布时间】:2016-11-15 05:28:10
【问题描述】:
我有一个将历史结果记录到文件的数据库。
将结果记录到由
创建的表中CREATE TABLE Data (TimeID INTEGER NOT NULL REFERENCES StartTimes,
TimeOffset REAL,
SensorID INTEGER NOT NULL REFERENCES Sensors,
Value REAL);
我有一个超过 (TimeID, TimeOffset) 的索引,可以根据需要创建更多 - 我的 INSERT 性能暂时还不错,希望应该保持这样。
我读出数据以将数据放在图表上使用
SELECT SensorID, TimeOffset, Value from Data
WHERE ((TimeID = %d AND TimeOffset BETWEEN %f AND %f) AND
(%s));
其中 %s 由字符串替换,效果为“(SensorID=1 and ROWID%5=0) or (SensorID=2 and ROWID%5000=0)”,%d 是准备好的语句中的常量值, %f 必然与图的界限相对应。
我的问题是,如果我有两个传感器记录相同的速率,每个传感器记录一个点,并且如果我使用取模的值变成例如2,然后我从一个传感器获取所有数据,而从另一个传感器获取任何数据(我认为?)。
我尝试过使用
SELECT COUNT(lesser.TimeOffset) as NewID, D.TimeOffset from Data as D
LEFT OUTER JOIN Data as lesser on D.rowid > lesser.rowid and D.TimeID=%d and D.SensorID=1
GROUP BY D.TimeOffset;
但在命令行上(使用 TimeID 的示例值)命令行处理了很长时间(可能我完全写错了语句)。
如何使用这些约束(TimeID=?、TimeOffset BETWEEN ? AND ?)选择数据子集,并通过 SensorID 快速抓取不受写入其他测量值影响的集合?
理想情况下,我希望能够使用 MIN(x) 和 MAX(x) 来查找给定 TimeOffset 范围内的最高和最低值,但我似乎无法快速做到这一点(即我可以锻炼 - 不过我是 SQL(ite) 的新手)。因此,我只选择了 % 运算符。
编辑 - 示例表内容:
SELECT * from Data LIMIT 10;
TimeID|TimeOffset|SensorID|Value
1|0.0|1|0.464069664478302
1|0.0|2|0.0
1|0.00100000004749745|2|0.00251327152363956
1|0.0020000000949949|2|0.00502652721479535
1|0.00300000002607703|2|0.00753975100815296
1|0.00400000018998981|2|0.010052926838398
1|0.00499999988824129|2|0.0125660402700305
1|0.00600000005215406|2|0.0150790736079216
1|0.00700000021606684|2|0.0175920110195875
1|0.00800000037997961|2|0.0201048385351896
使用我的合成数据(用于测试实施),我有一个介于 0 和 1 之间的随机数作为 1Hz 的传感器 #1,以及一个正弦波作为 1kHz 的 #2。 (这些不是一次写的,但我仍然觉得我可以使用 rowid%x 来抽取自己的脚)
TimeOffset 测量自数据采集开始以来的时间,而 TimeID 引用 StartTimes 表(YmDHMS 等)中的 StartTime。
理由
由于屏幕上的像素通常远少于可放置在相关时间跨度内的点数,因此只选择一些点以减少我尝试从数据库中读取的数据量是明智的。
使用 % 运算符可以得到均匀分布的点,但在某些情况下很容易丢失数据的形状。
使用最小/最大抽取可以防止这种情况,但要使用它,您需要在每个时间跨度中找到最小值和最大值,例如一个像素的宽度。如果我不在查询中执行此操作,那么我必须从数据库中读取图表边界之间的所有数据,其中我可能只会绘制一小部分(低于 1%)。
【问题讨论】:
-
我也可以考虑为每个传感器使用单独的表,但我不确定这会是一个更快的想法。不过,它会从问题中删除其他传感器的结果,这可能是值得的。
-
如果您添加以下示例可能会有所帮助:您的表格内容、当前检索到的结果及其查询以及所需的结果。
-
看来
WITH子句可以显着改善我的查询。我可以使用它们只取整个Data表的一小部分,然后在该子集上执行JOIN,而没有对ON子句的额外约束(这似乎是问题)。子查询不允许使用索引吗?还是我发布的查询永远不会超过JOIN?
标签: sql select sqlite subquery