実際に Elasticsearch(索引検索)と grep(逐次検索)でどれくらい速度が違うのか試してみました。
検索について
逐次検索とは
ドキュメントを先頭から末尾まで見てキーワードとマッチするかを見る方式です。
代表的なものは grep です。
この方式は検索対象のファイル数が多くなるとそれだけ検索に時間がかかるようになります。
索引検索とは
ドキュメントから転置インデックスを作成し、インデックスにキーワードが含まれているかを見る検索方式です。
代表的なものは Elasticsearch、Solr です。
事前にドキュメントから転置インデックスを作成する必要がありますが、大量のドキュメントでも高速で検索できます。
実験
では早速実験です。
grep
ドキュメントを用意します。
$ cd ~
$ mkdir extracted/docs
$ cd extracted/docs
# ndjson を1行ごと抽出する
$ ls ~/extracted/AA.bak/* | xargs -L 1 -P 10 bash -c 'echo $0; split -l 1 -d $0 `basename $0`'
ドキュメント数は 117 万です。
$ cd ~/extracted/docs
$ ls -U1 | wc -l
1175109
では grep してみます。
$ grep -e "全文検索エンジン" -e "Elasticsearch" ./*
-bash: /bin/grep: Argument list too long
ドキュメントが多すぎて怒られました。
find して grep します。
$ time find . -type f | xargs -L 1 -P 1000 bash -c 'grep -e "Elasticsearch" -e "全文検索エンジン" $0'
{"url": "https://ja.wikipedia.org/wiki?curid=182460", "text": "KAKASI\n\nKAKASI(かかし)は、日本語の漢字仮名交じり文を平仮名やローマ字綴りの文に変換するプログラムである。単語ごとにわかち書きができる機能により形態素解析エンジンとしてNamazu
等の全文検索エンジンと組み合わせて用いられることも多い。...", "id": "182460", "title": "KAKASI"}
{"url": "https://ja.wikipedia.org/wiki?curid=555433", "text": "Senna\n\nSenna(せな、Senna: An Embeddable Fulltext Search Engine)は、未来検索ブラジルによって開発されているオープンソースの全文検索エンジンである。...", "id": "555433", "title": "Senna"}
...
real 90m19.993s
user 29m14.314s
sys 15m12.245s
90 分 もかかりました。
Elasticsearch
インデックス情報
ドキュメント数は 117 万、インデックスのサイズは 5.84 GB です。
$ curl -X GET 'http://localhost:9200/wiki/_stats?pretty' -s | jq '{ count: .indices.wiki.primaries.docs.count, size: .indices.wiki.primaries.store.size_in_bytes }'
{
"count": 1175109,
"size": 6272333867
}
検索
「全文検索エンジン Elasticsearch」で検索します。
$ curl -s -XGET 'http://localhost:9200/wiki/_search?pretty' -d '{"query":{"bool":{"should":[{"match":{"text": "全文検索 Elasticsearch"}},{"match":{"title": "全文検索 Elasticsearch"}}]}}}' -H 'Content-Type: application/json
'
{
"took" : 102,
"timed_out" : false,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10000,
"relation" : "gte"
},
"max_score" : 239.99734,
"hits" : [
{
"_index" : "wiki",
"_type" : "_doc",
"_id" : "mcWiYm4BvfCPgCEA1xL2",
"_score" : 239.99734,
"_source" : {
"url" : "https://ja.wikipedia.org/wiki?curid=3479729",
"text" : "Elasticsearch\n\nElasticsearchはLucene基盤の分散処理マルチテナント対応検索エンジンである。...",
"id" : "3479729",
"title" : "Elasticsearch"
}
},
{
"_index" : "wiki",
"_type" : "_doc",
"_id" : "GsWiYm4BvfCPgCEA1yn4",
"_score" : 159.24606,
"_source" : {
"url" : "https://ja.wikipedia.org/wiki?curid=3502571",
"text" : "Butterfly search\n\nbutterfly_search (バタフライサーチ) は、Microsoft Windows向けのデスクトップ検索ツールである。\n\n\n\n他の全文検索ツールにない特徴としては...",
"id" : "3502571",
"title" : "Butterfly search"
}
},
...
]
}
}
たった 106 ms で検索が完了しました。
全ての検索結果は載せてませんが、先頭に最も欲しい情報が出てきました。
まとめ
117 万件のドキュメントを検索した結果、Elasticsearch では 106 ms、grep では 90 分 かかりました。
Elasticsearch のほうが grep よりも 50943 倍 検索が早かったです!
検索条件やサーバースペックによって結果は変わると思いますが、Elasticsearch の実力を見るには十分な実験になりました。