Closed s-yata closed 9 years ago
以下のようにしました.
table_create Table TABLE_NO_KEY
column_create Table Body --type Text
column_create Table Length --type Int64
column_create Table RandInt --type Int64
column_create Table RandFloat --type Float
table_create IntIndex TABLE_PAT_KEY Int64
column_create IntIndex RandInt COLUMN_INDEX Table RandInt
クエリは以下の 2 種としました.
Threshold
を変更することで検索結果に含まれるレコード数を調整します.
select Table --limit -1 --filter 'RandInt < Threshold'
select Table --output_columns '_id,_score' --limit -1" --filter 'RandInt < Threshold'
まず,検索結果のサイズを以下に示します.
Threshold | OutputAll | ID, Score |
---|---|---|
1 | 15KB | 1KB |
10 | 142KB | 12KB |
100 | 1,360KB | 108KB |
1,000 | 13,656KB | 1,082KB |
10,000 | 138,632KB | 10,889KB |
次に,検索に要した時間を示します.
Threshold | OutputAll | ID, Score |
---|---|---|
1 | 2ms | 1ms |
10 | 5ms | 2ms |
100 | 40ms | 6ms |
1,000 | 270ms | 61ms |
10,000 | 2,674ms | 388ms |
これらの結果より,本文をまとめて返すとかなり時間がかかることがわかります. 本実験では 100bytes 程度の短い Text なので,より長い Text を使えば,その分だけ時間がかかるものと予想されます.
ID, Score のみを返す場合,本文などを含めた場合よりは短時間で終わります. しかし,レコード数 1,000,000 で 388ms というのは,かなり厳しい数字のように思えます.
Goroonga より得られた結果を Grnxx に渡せる形式に変換し,それを Grnxx で絞り込み,その結果をまた出力用の形式に戻さなければなりません. 絞り込みの条件が単純であれば,おそらく Groonga 側で絞り込みも片付ける方が効率的でしょう.
参考までに,データベースの構成から索引を取り除いたらどうなるかを示します. 具体的には,以下のコマンドを取り除いただけです.
table_create IntIndex TABLE_PAT_KEY Int64
column_create IntIndex RandInt COLUMN_INDEX Table RandInt
Threshold | OutputAll | ID, Score |
---|---|---|
1 | 167ms | 167ms |
10 | 170ms | 166ms |
100 | 194ms | 175ms |
1,000 | 399ms | 206ms |
10,000 | 2,198ms | 454ms |
索引を取り除いたため,検索は全走査になっているはずです.
この結果から, RandInt < Threshold
という単純な条件による絞り込みにかかる時間は 160-170ms とわかります(※).
※ ID 昇順に絞り込みできるので,索引を使った後に絞り込みをするケースとは条件が異なります.
さらに,先の結果と併せれば, 1,000,000 万件の ID, Score を受け取るのには 300ms 程度が想定されます.
このことから,少なくとも RandInt < Threshold
のような単純な絞り込みについては, Groonga 側ですべて片付けた方が効率的になる可能性が高そうです.
--output_type msgpack
を試してみます.
索引ありの状態で,以下のクエリについて Threshold
を変更しつつ実行時間を計測してみました.
計測したのは結果を受け取るまでで,検索結果のパースなどは含みません.
単純に出力の書式による実行時間の違いを確認しただけです.
select Table --limit -1 --filter 'RandInt < Threshold'
select Table --limit -1 --filter 'RandInt < Threshold' --output_type msgpack
Threshold | Json | Msgpack |
---|---|---|
1 | 3ms | 3ms |
10 | 8ms | 8ms |
100 | 37ms | 26ms |
1,000 | 299ms | 186ms |
10,000 | 2,802ms | 1,976ms |
Json より Msgpack の方が速いことを確認できました. Goroonga と Grnxx の連携については復号のコストも関わってくるので, Msgpack がより有利になるのではないかと思います.
さらに,クエリに --output_columns '_id,_score'
を加えて ID, Score のみを返すようにすると以下のようになりました.
Threshold | Json | Msgpack |
---|---|---|
1 | 1ms | 1ms |
10 | 6ms | 2ms |
100 | 15ms | 5ms |
1,000 | 47ms | 34ms |
10,000 | 427ms | 370ms |
想定より差が小さいものの, Msgpack の方が少し速くなることを確認できました. 検索自体のコストもあるので,こんなものでしょうか.
ちなみに, Json より Msgpack の方がデータサイズも少し小さくなります. 可読性が必要なく,バイナリによるやり取りで問題ない状況であれば,基本的に Msgpack の方が効率的になりそうです.
概要
Groonga との連携を検証するため, Goroonga で検索結果の受け取りにかかる時間を調べます.
具体的には,検索結果に含まれるレコード数を調整しつつ,検索結果(ID, Score)の受け取りにかかる時間を計測します. ついでに,カラムの内容を受け取るのにかかる時間も調べます.
検索結果の受け取りにかかる時間が絞り込みにかかる時間と比べて十分に短くなければ, Grnxx と組み合わせても検索時間を短縮するのは難しいということになります.