いくつかの所見:
- あなたのクエリは、単一のトランザクションで2 * 600 * 599(または718800)
MERGE
操作を実行しようとします。 2
の理由は、すべての単語のペア(xとyなど)が2回(x/yとy/xとして)表示されるためです。あなたは(おそらく)半分の操作しか実行したくないでしょう。
- x/yとy/xの振る舞いによって、単語のペアごとに2つの方向(1つずつ)が存在することを確認します。それはあなたが望む(または必要な)関係の数の(おそらく)倍の数です。
- 単一トランザクションで720K(またはさらに360K)の操作を実行しようとすると、DBサーバーのメモリが不足する可能性があります。
上記の問題を修正する可能性のある変更されたクエリです。 ID(w1) < ID(w2)
テストでは、ペア内の2語が同じでなく、同じペアが1回だけ処理されることを確認します。また、APOC手順apoc.periodic.iterateを使用して、別々のトランザクションで同時に10Kリレーションシップを作成します。
CALL apoc.periodic.iterate(
'MATCH (w1:Word), (w2:Word) WHERE ID(w1) < ID(w2) RETURN w1, w2',
'CREATE (w1)-[:DISTANCE]->(w2)',
{batchSize:10000, parallel:true}) YIELD batches, total
RETURN *
注1:このクエリを使用すると、DBのいずれかのDISTANCE
関係なしに開始することを前提としていますので、代わりにMERGE
の安いCREATE
句を使用しています。 DISTANCE
の関係が既に存在する場合は、代わりにMERGE
を使用します(ただし、最初の関係が反対の場合は、同じペアの間に2番目の関係が作成される可能性があります)。
注2:新しいCypherコードでは問題2が不可能なため、バッチを並行して実行することは安全です。 2つのトランザクションが同じ2つのノード間で逆方向の関係を同時に作成しようとすると、deadlockという結果になり、少なくとも1つのトランザクションが失敗する可能性があります。
注3:このクエリでは、最初のステートメント(MATCH
句付き)は、メモリ不足または処理に時間がかかりすぎないと仮定しています。その前提が間違っている場合は、適切に変更されたクエリを使用してapoc.periodic.commitを使用すると効果があります。
これは、1回のトランザクションで作成された360Kのリレーションシップで、メモリ設定によって大きく異なる可能性があります。 –
また、360Kの行を戻していることに注意してください。少なくとも、あなたがそれを必要としないように見えるので、あなたのリターンを排除することができます。また、DISTANCE関係に変数を追加する必要はありません。クエリでこれ以上何もしない場合は、マージをバッチアップする必要がある場合は、APOCライブラリプロシージャapoc.periodic.commit()を試してください。 – InverseFalcon