2016-11-15 44 views
0

我有一個數據庫將歷史結果記錄到文件。快速選擇數據而沒有其他行干擾%(mod)運算符

結果記錄到由

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和ROWID%5 = 0)或(SensorID =效果放置在圖表上的數據2和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 

用我的由數據(被用於測試實現)我有作爲傳感器#1以1Hz 0和1之間的隨機數,和一個正弦波在1kHz處爲#2。 (這些不是一次寫入一個點,但我仍然覺得我可以使用rowid%x來抽空自己)

TimeOffset測量自從數據採集開始以來的時間,而TimeID引用了a StartTimes表中的StartTime(YmDHMS等)。

理由

由於有屏幕比可在相關時間跨度放置點的數量上往往遠遠少於像素,只選擇一些點是明智的,以減少數據的我量試圖從數據庫中讀取。

使用%運算符會給我均勻間隔的點,但在某些情況下很容易丟失數據的形狀。

使用最小/最大抽取可以防止這種情況發生,但要使用它,需要在每個時間範圍內找到與例如最小值和最大值相對應的最小值和最大值。一個像素的寬度。如果我不在查詢中這樣做,那麼我必須從圖的邊界之間讀取數據庫中的所有數據,其中我可能只繪製一些小的(小於1%)分數。

+0

我也可以考慮爲每個傳感器使用單獨的表格,但我不確定這會是一個更快的想法。它會從這個問題中刪除其他傳感器的結果,這可能是值得的。 – chrisb2244

+0

如果您添加以下示例,可能會有所幫助:您的表格內容,當前檢索結果及其查詢以及所需結果。 – FDavidov

+0

看起來'WITH'子句可以顯着改善我的查詢。我可以使用它們只佔整個Data表的一小部分,然後在該子集上執行JOIN,而沒有對ON子句的附加限制(這似乎是「ON」子句的很大一部分)問題)。子查詢是否不允許使用索引?或者是我發佈的查詢只是永遠不會超過'JOIN'? – chrisb2244

回答

1

您可以嘗試使用子查詢計算數據採集系列內條目的索引,但這會很慢。

過濾掉不需要的行的最有效的方法是可能做到這一點在你的程序,即查詢所有的人,以正確的順序,以及剛剛跨過所有的人除了每個ñ個。 (這需要排序,但因爲結果是由於該指數已經排序ORDER BY TimeID, TimeOffset沒有任何費用。)

您可以通過使用covering index進一步提高您的查詢,但對於這個表,用PK一clustered index(在前三欄中)會更好。 此外,由於only the right-most used column in an index can optimize inequalities,使得柱體的順序爲TimeID, SensorID, TimeOffset

+0

我知道,當我使用'SELECT'語句時,我應該按照'TimeID,SensorID,TimeOffset'的順序使用約束,但我只是想檢查一下 - 是你在這裏的意思,還是按照順序列由'CREATE TABLE'存儲也會對性能產生影響?我會看看使用'WITHOUT ROWID'表,看看我是怎麼做的 - 只要我像應用程序那樣處理應用程序而不是數據庫,就可以這樣做(因爲我可以使用數組索引) – chrisb2244

+0

The在SELECT語句中的順序無關緊要,只有索引中的順序。 (在聚集索引中,這是表格順序。) –

+0

糟糕。更好的檢查我沒有搞砸了。將重讀聚集索引。 – chrisb2244