UPDATE更新されたスクリプトと、mysqlと比較してneo4jのパフォーマンスに関するより明確なセットアップを含むフォローアップの質問を提出しました(どのように改善できますか?)。そこで続けてください。/アップデート
「グラフ データベース」の本 (20 ページ) と neo4j (第 1 章) で述べられているパフォーマンスの主張を検証するのに、いくつか問題があります。
これらの主張を検証するために、それぞれ 50 人の「友人」を持つ 100000 の「人」エントリのサンプル データセットを作成し、たとえば 4 ホップ離れた友人のクエリを試みました。mysql でまったく同じデータセットを使用しました。友人の友人が 4 ホップ以上の場合、 mysql は 0.93 秒で戻りますが、neo4j は 65 ~ 75 秒 (繰り返し呼び出しの場合) を必要とします。
どうすればこの悲惨な結果を改善し、本でなされた主張を検証できるでしょうか?
もう少し詳しく:
ubuntu12.04 64ビット、Javaバージョン「1.7.0_25」、およびmysql 5.5.31、neo4j-community-2.0.0-M03を使用して、16GB RAMを搭載したi5-3570Kでセットアップ全体を実行します(1.9でも同様の結果が得られます)
すべてのコード/サンプル データは、https://github.com/jhb/neo4j-experiments/ (2.0.0 で使用) にあります。結果として得られるさまざまな形式のサンプル データは、https://github.com/jhb/neo4j-testdataにあります。
スクリプトを使用するには、mysql-python、requests、および simplejson がインストールされた python が必要です。
- データセットは friendsdata.py で作成され、 friends.pickle に保存されます
- friends.pickle は import_friends_neo4j.py を使用して neo4j にインポートされます
- friends.pickle は import_friends_mysql.py を使用して mysql にインポートされます
- mysql で t_user_friend.* にインデックスを追加します
- 「neo4j で :node(noscenda_name) にインデックスを作成する」を追加しました
生活を少し楽にするために、friends.*.bz2 には、mysql および neo4j 2.0 M3 でこれらのデータセットを作成するための sql および cypher ステートメントが含まれています。
Mysql のパフォーマンス
最初にクエリを実行して mysql をウォームアップします。
select count(distinct name) from t_user;
select count(distinct name) from t_user;
次に、実際の測定のために私が行います
python query_friends_mysql.py 4 10
これにより、次の sql ステートメントが作成されます (t_user.names を変更)。
select
count(*)
from
t_user,
t_user_friend as uf1,
t_user_friend as uf2,
t_user_friend as uf3,
t_user_friend as uf4
where
t_user.name='person8601' and
t_user.id = uf1.user_1 and
uf1.user_2 = uf2.user_1 and
uf2.user_2 = uf3.user_1 and
uf3.user_2 = uf4.user_1;
この 4 ホップ クエリを 10 回繰り返します。クエリにはそれぞれ約 0.95 秒かかります。Mysql は 4G の key_buffer を使用するように構成されています。
neo4j のパフォーマンス テスト
neo4j.properties を変更しました。
neostore.nodestore.db.mapped_memory=25M
neostore.relationshipstore.db.mapped_memory=250M
そして neo4j-wrapper.conf:
wrapper.java.initmemory=2048
wrapper.java.maxmemory=8192
私がするneo4jをウォームアップするために
start n=node(*) return count(n.noscenda_name);
start r=relationship(*) return count(r);
次に、トランザクション http エンドポイントの使用を開始します (ただし、neo4j-shell を使用しても同じ結果が得られます)。
まだウォーミングアップ、私は走ります
./bin/python query_friends_neo4j.py 3 10
これにより、次の形式のクエリが作成されます (個人 ID が異なります)。
{"statement": "match n:node-[r*3..3]->m:node where n.noscenda_name={target} return count(r);", "parameters": {"target": "person3089"}
7 回目の呼び出しの後、各呼び出しには約 0.7 ~ 0.8 秒かかります。
今、本当のことのために(4ホップ)私はします
./bin/python query_friends_neo4j.py 4 10
作成
{"statement": "match n:node-[r*4..4]->m:node where n.noscenda_name={target} return count(r);", "parameters": {"target": "person3089"}
各呼び出しには 65 ~ 75 秒かかります。
未解決の質問/考え
本の主張が再現可能で正確であること、そしてneo4jがmysqlよりもはるかに遅いのではなく速いことを本当に望んでいます。
しかし、私は何が間違っているのかわかりません... :-(
だから、私の大きな希望は次のとおりです。
- neo4jのメモリ設定を正しくしていませんでした
- 私がneo4jに使用するクエリは完全に間違っています
neo4j を高速化するための提案は大歓迎です。
どうもありがとう、
ヨルグ