graph - 如何优化具有多个节点匹配的 Neo4j Cypher 查询(笛卡尔积)

标签 graph neo4j query-optimization cypher cartesian-product

我目前正在尝试合并三个数据集以进行分析。我正在使用某些公共(public)字段来建立数据集之间的连接。为了创建连接,我尝试使用以下类型的查询:

MATCH (p1:Person),(p2:Person)
WHERE p1.email = p2.email AND p1.name = p2.name AND p1 <> p2 
CREATE UNIQUE (p1)-[IS]-(p2);

可以类似地写为:

MATCH (p1:Person),(p2:Person {name:p1.name, email:p1.email})
WHERE p1 <> p2 
CREATE UNIQUE (p1)-[IS]-(p2);

不用说,对于具有大约 100,000 个 Person 节点的数据库来说,这是一个非常慢的查询,特别是考虑到 Neo4j 不并行处理单个查询。

现在,我的问题是是否有更好的方法在 Neo4j 中运行此类查询。我至少有 8 个 CPU 核心专用于 Neo4j,只要单独的线程不会通过锁定彼此所需的资源而陷入困境。

问题是我不知道 Neo4j 如何构建其 Cypher 执行计划。例如,假设我运行以下测试查询:

MATCH (p1:Person),(p2:Person {name:p1.name, email:p1.email})
WHERE p1 <> p2 
RETURN p1, p2
LIMIT 100;

尽管有 LIMIT 子句,Neo4j 仍然需要相当多的时间来返回结果,这让我想知道即使对于这样一个有限的查询,Neo4j 是否会在考虑 LIMIT 语句之前生成整个笛卡尔积表。

我感谢任何帮助,无论它解决了这个特定问题,还是只是让我了解 Neo4j 通常如何构建 Cypher 执行计划(以及如何优化一般查询)。遗留的 Lucene 索引在这里有什么帮助吗?

最佳答案

您可以对 p1 进行标签扫描,然后对 p2 进行索引查找和比较:

看这里:

cypher 2.1 
foreach (i in range(1,100000) | 
  create (:Person {name:"John Doe"+str(i % 10000),
                   email:"john"+str(i % 10000)+"@doe.com"}));
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 100000
Properties set: 200000
Labels added: 100000
6543 ms
neo4j-sh (?)$ CREATE INDEX ON :Person(name);
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1
28 ms

neo4j-sh (?)$ schema
Indexes
  ON :Person(name)  ONLINE

neo4j-sh (?)$ 
match (p1:Person) with p1 
match (p2:Person {name:p1.name}) using index p2:Person(name) 
where p1<>p2 AND p2.email = p1.email 
return count(*);
+----------+
| count(*) |
+----------+
| 900000   |
+----------+
1 row
8206 ms

neo4j-sh (?)$ 
match (p1:Person) with p1 
match (p2:Person {name:p1.name}) using index p2:Person(name) 
where p1<>p2 AND p2.email = p1.email
merge (p1)-[:IS]-(p2) 
return count(*);

+----------+
| count(*) |
+----------+
| 900000   |
+----------+
1 row
Relationships created: 450000
40256 ms

关于graph - 如何优化具有多个节点匹配的 Neo4j Cypher 查询(笛卡尔积),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24437344/

相关文章:

用于类别理论(或图形)图的 javascript 包?

php - 不同日期范围的 Highcharts 图 X 轴标签

java - 当你有多个来源和多个目的地时,有没有比 A* 更好的寻路算法?

Neo4J-密码 : Collect Several Return Values to avoid duplicates

mysql - 使用 MAX() 优化 MYSQL 查询

java - 内部静态泛型类<<无法解析为类型>>

neo4j - 从 OWL 本体到 Neo4j 图数据库的映射

linux - 在 ArchLinux 下使用 Pydev 在 Eclipse 中运行 neo4j-Python 代码

sql-server-2008 - T-SQL 优化的条件连接

mysql - LIMIT 0,1 会加速主键上的 SELECT 吗?