sqlite3 でデータロガーを作るためのテスト。

可変数データを保存できるデータロガーのデータ保存部を sqlite3 で書いたとしたら、何データまで保存できるかをテストしてみる。
具体的にはデータベースに
測定値の種類、測定時刻、測定値
を記録する。読み出しは読み出したいデータを where で抽出する。こうすれば、二次元でデータを用意しなくてもすむのでださくないけど、普通に考えて遅そう。そんなわけでどれくらいまでいけるか、というのをテストした。
結果は Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz 上でテストしたところ、

データレコード数 抽出にかかる時間[s]
1e5 0.03
1e6 0.3
1e7 3.

というところだった。実際問題1e6個のデータレコードが限界みたいだ。

#!/usr/bin/python
import sqlite3
import time
import string
import random
import pylab
digits=2
numoftrial=int(1e6)

alphabets = string.digits

print "I have %.0f items and have %d records which is about %.0f data per item." % ( pow(len(alphabets),digits), numoftrial, numoftrial/pow(len(alphabets),digits) )

def randstr(n):
    return ''.join(random.choice(alphabets) for i in xrange(n))

con = sqlite3.connect(":memory:")
# Create the table
con.execute("create table person(item, time, value)")

# Fill the table
print "now added", time.clock()
for i in xrange(numoftrial):
	con.execute("insert into person(item, time, value) values ('%s', %d, %f)" % (randstr(digits),i,random.random()) )
con.commit()

print "let's show you", time.clock()
for i in range(3):
	starttime=time.clock()
	t0=[]
	v0=[]
	for row in con.execute("select time, value from person where item = '%s' and time > 400000 and time < 410000" % randstr(digits)):
		(a,b)=row
		t0.append(a)
		v0.append(b)

	endtime=time.clock()
	print "%d times match in %d of trial" % ( len(t0), numoftrial ), "Elapsed time %f [sec]" % ( endtime - starttime )
	pylab.plot(t0,v0)
pylab.xlabel('trial number')
pylab.ylabel('value')
pylab.title('Data logger benchmark: %.0f kinds of data and %.0f times meas. on average' % (pow(len(alphabets),digits), numoftrial/pow(len(alphabets),digits)) )
pylab.show()

print "I just deleted", con.execute("delete from person where 1=1").rowcount, "rows"
con.clock()

どっかからいただいてきた乱数を作る python スクリプトを改変。

こんなデータが出てきて、

sqlite> select * from person limit 10;
item|time|value
27|0|0.983709
00|1|0.456427
25|2|0.1306
21|3|0.424554
32|4|0.183771
01|5|0.215679
58|6|0.558124
97|7|0.508473
42|8|0.44731
32|9|0.900506

where で選ぶと

sqlite> select * from person where item = '10' limit 10;
item|time|value
10|67|0.190627
10|138|0.608336
10|188|0.40195
10|245|0.476355
10|327|0.079208
10|351|0.468487
10|446|0.019215
10|538|0.556738
10|721|0.63735
10|825|0.944074

参考