CSVからデータをインポートした後、GeneとChromosomeという2つのエンティティ間の関係を、シンプルで通常の方法で定義しています。
MATCH (g:Gene),(c:Chromosome)
WHERE g.chromosomeID = c.chromosomeID
CREATE (g)-[:PART_OF]->(c);
しかし、私がそうするとき、neo4j(ブラウザUI)は不平を言います:
このクエリは、切断されたパターン間のデカルト積を構築します。クエリの一部に複数の切断されたパターンが含まれている場合、これらのすべての部分間にデカルト積が構築されます。これにより、大量のデータが生成され、クエリ処理が遅くなる可能性があります。意図されることもありますが、おそらく異なるパーツ間の関係を追加するか、OPTIONAL MATCH(識別子は:(c))を使用することにより、このクロス積の使用を回避するクエリを再定式化できる場合があります。
問題が何であるかわかりません。染色体IDは非常に単純な外部キーです。
ブラウザは次のように言っています:
Gene
インスタンスとすべてのChromosome
インスタンスを比較してクエリを処理しています。 DBにG
遺伝子とC
染色体がある場合、クエリの複雑さはO(GC)
です。たとえば、ヒトゲノムを扱っている場合、46の染色体とおそらく25000の遺伝子があるため、DBは_1150000
_の比較を行う必要があります。クエリを変更することで、複雑さ(およびパフォーマンス)を改善できる可能性があります。たとえば、 created a index on :Gene(chromosomeID)
を実行し、クエリを変更して、最初にカーディナリティが最小のノード(46染色体)のみに一致するようにした場合、 do O(G)
(または_25000
_)の「比較」-そして、それらの比較は実際には迅速なインデックス検索になります!これは、はるかに高速なアプローチです。
インデックスを作成したら、次のクエリを使用できます。
_MATCH (c:Chromosome)
WITH c
MATCH (g:Gene)
WHERE g.chromosomeID = c.chromosomeID
CREATE (g)-[:PART_OF]->(c);
_
WITH
句を使用して、最初のMATCH
句を強制的に最初に実行し、デカルト積を回避します。 2番目のMATCH
(およびWHERE
)句は、最初のMATCH
句の結果とインデックスを使用して、各染色体に属する正確な遺伝子をすばやく取得します。
Logisimaがコメントで言及しているように、これは単なる警告です。デカルト積のマッチングは遅いです。以前は接続されていなかったGene
およびChromosome
ノードを接続する必要があり、デカルト積のサイズがわかっているため、この場合は問題ありません。染色体が多すぎず、遺伝子の数が少ない。 MATCH
の場合、たとえばクエリが吹き飛ばす可能性のあるタンパク質上の遺伝子。
警告は他の問題のあるクエリを対象としていると思います。
MATCH
デカルト積であるが、関係があるかどうかわからない場合は、OPTIONAL MATCH
を使用できますMATCH
Gene
とChromosome
の両方を使用したい場合は、クエリを分割する必要がありますクエリに時間がかかりすぎるか終了しない場合は、デカルト積を最適化する方法のヒントを示す別の質問があります。 複数のノードが一致するNeo4j Cypherクエリを最適化する方法(デカルト積)