SQLiteかわいいよSQLite(※ただしlimitに限る)

id:minghaiさんがLIMITしたらどうよ?とおっしゃってたので、やってみた。まずLIMITっぅのの使い方がわからいない(レベル低っ;><)なので、Ubuntuで普通に試した。

$ time sqlite3 skk_dict.db "select * from dictionary where key like 'a%';" > /dev/null
real    0m0.409s
user    0m0.280s
sys     0m0.076s

$ time sqlite3 skk_dict.db "select * from dictionary where key like 'a%' limit 1000;" > /dev/null
real    0m0.083s
user    0m0.036s
sys     0m0.016s

(@_@;)なにこれ?LIMITなしだと280msec、LIMIT 1000で36msec。10倍違う。対象レコードは1614件なのに。

$ time sqlite3 skk_dict.db "select * from dictionary where key like 'a%' limit 100;" > /dev/null
real    0m0.074s
user    0m0.036s
sys     0m0.000s

$ time sqlite3 skk_dict.db "select * from dictionary where key like 'a%' limit 10;" > /dev/null
real    0m0.072s
user    0m0.024s
sys     0m0.008s

$ time sqlite3 skk_dict.db "select * from dictionary where key like 'a%' limit 1;" > /dev/null
real    0m0.086s
user    0m0.036s
sys     0m0.004s

(@_@;)なにこれ?LIMIT数にはあまり関係ない。もう一回LIMITを外してみた。

$ time sqlite3 skk_dict.db "select * from dictionary where key like 'a%';" > /dev/null
real    0m0.361s
user    0m0.300s
sys     0m0.024s

\(^o^)/


ということで、ZaurusのAngstrom環境、Androidchrootする前の状態で試してみた。

root@spitz:~$ file ./sqlite3
./sqlite3: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.14, dynamically linked (uses shared libs), stripped

root@spitz:~$ ./sqlite3 --version
3.5.2

root@spitz:~$ time ./sqlite3 ./donut/data/anr/skk_dict.db "select count(*) from dictionary where key like 'a%';"             
1614
real    0m 2.15s
user    0m 1.88s
sys     0m 0.27s

root@spitz:~$ time ./sqlite3 ./donut/data/anr/skk_dict.db "select * from dictionary where key like 'a%' limit 1614;" > /dev/null 
real    0m 0.36s
user    0m 0.28s
sys     0m 0.08s

root@spitz:~$ time ./sqlite3 ./donut/data/anr/skk_dict.db "select * from dictionary where key like 'a%' limit 1615;" > /dev/null 
real    0m 2.26s
user    0m 2.03s
sys     0m 0.23s

(@_@;)同じ傾向。なんてこったい。というわけで、Androidのシェル上で試してみた。こんなスクリプト

#!/system/bin/sh

echo "count"
busybox time /system/xbin/sqlite3 /data/anr/skk_dict.db "select count(*) from dictionary where key like 'a%';"

echo "limit 1614"
busybox time /system/xbin/sqlite3 /data/anr/skk_dict.db "select * from dictionary where key like 'a% limit 1614';" > /dev/null

echo "limit 1615"
busybox time /system/xbin/sqlite3 /data/anr/skk_dict.db "select * from dictionary where key like 'a%' limit 1615;" > /dev/null

echo "limit 1"
busybox time /system/xbin/sqlite3 /data/anr/skk_dict.db "select * from dictionary where key like 'a%' limit 1;" > /dev/null

echo "limit 10"
busybox time /system/xbin/sqlite3 /data/anr/skk_dict.db "select * from dictionary where key like 'a%' limit 10;" > /dev/null

echo "limit 100"
busybox time /system/xbin/sqlite3 /data/anr/skk_dict.db "select * from dictionary where key like 'a%' limit 100;" > /dev/null

echo "limit 1000"
busybox time /system/xbin/sqlite3 /data/anr/skk_dict.db "select * from dictionary where key like 'a%' limit 1000;" > /dev/null


(@_@;)LIMIT効果絶大。あとAndroid上では、1614と1615での結果が逆転している。なぜゆえ?


ということを踏まえて、SQLiteTestにLIMIT 1000をつけて、実験。github*1sqlite-zaurus-like-limit1000.traceを含めてアップデートしてある。

(@_@;)なにこれ?6秒が700msecに。SQLiteのselectでlikeするときはlimitつけるのって常識なのかしら。ということで、SQLiteかわいいよSQLite(※ただしlimitに限る)