SQLite3の列からCSVデータを抽出するならLIKEよりGLOBのほうが速いらしい
というか、今までGLOB
を知らなかった。
情報源
LIKE
句よりGLOB
句のほうが速いらしい。
試してみる
以下コマンドをターミナルにコピペして実行。
sqlite3 create table TBL(id primary key, name text); insert into TBL(id,name) values(1,'AAA'); insert into TBL(id,name) values(2,'AAA,BBB'); insert into TBL(id,name) values(3,'ZZZ,AAA'); insert into TBL(id,name) values(4,'ZZZ,AAA,BBB'); insert into TBL(id,name) values(5,'AA'); insert into TBL(id,name) values(6,'BBB'); insert into TBL(id,name) values(7,'AAAA'); select * from TBL; select * from TBL where (',' || name || ',') like '%,AAA,%'; select * from TBL where (',' || name || ',') glob '*,AAA,*'; select * from TBL where name='AAA' or name glob 'AAA,*' or name glob '*,AAA' or name glob '*,AAA,*';
全データを一覧する。
sqlite> select * from TBL; 1|AAA 2|AAA,BBB 3|ZZZ,AAA 4|ZZZ,AAA,BBB 5|AA 6|BBB
これをAAA
が含まれるデータのみ抽出したい。期待される出力は以下。
1|AAA 2|AAA,BBB 3|ZZZ,AAA 4|ZZZ,AAA,BBB
以下のように,
が有るときと無いときを一発で表現できないかと思ったが、1件も出ず……。まあ?
の意味は「任意の1字」であって「()内パターンが1回出るときと出ないとき」ではないので当然。
select * from TBL where name glob '*+(,)?AAA(,)?*+';
LIKE
句なら以下で表現できる。
select * from TBL where (',' || name || ',') like '%,AAA,%';
以下でもできた。
select * from TBL where (',' || name || ',') glob '*,AAA,*';
diesel
Rustのクレートであるdieselにglob()
メソッドはあるか? 検索してみたが無かった。
代わりに、生のSQL文を発行すると思われるメソッドをみつけた。
let users = sql_query("SELECT * FROM users ORDER BY id") .load(&connection);
所感
GLOB
で全文検索できるのでは?
LIKE
は遅すぎて使えないらしい。full-text searches 4, 5は難易度が高すぎて実装できない。でもGLOB
なら使えそう。where content glob '*検索キーワード*'
とすればいい。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
- sqlite3 3.22.0 2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux