やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

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のクレートであるdieselglob()メソッドはあるか? 検索してみたが無かった。

 代わりに、生の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