Neo4j 匹配查询在CYPHER中花费太多时间

Neo4j 匹配查询在CYPHER中花费太多时间,neo4j,cypher,Neo4j,Cypher,我正在为不同的查询使用CYPHER,而我的匹配查询花费了太多时间 查询: MATCH (a:FacebookComment), (b:FacebookLike) WHERE a.post_id > 696 AND a.post_id < 746 AND a.id = toint(b.comment_id) CREATE (a) <-[fpl:FB_COMMENT_LIKE]-(b) 匹配(a:FacebookComment),(b:FacebookLike) 其中a.

我正在为不同的查询使用CYPHER,而我的
匹配
查询花费了太多时间

查询:

MATCH (a:FacebookComment), (b:FacebookLike)

WHERE a.post_id > 696
AND
a.post_id < 746 
AND 
a.id = toint(b.comment_id)

CREATE (a) <-[fpl:FB_COMMENT_LIKE]-(b)
匹配(a:FacebookComment),(b:FacebookLike)
其中a.post_id>696
及
a、 邮政编码<746
及
a、 id=toint(b.comment\u id)
创建(a)696和a.post_id<746
将a.id=toint(b.comment\u id)中的(b:facebook-like)与b匹配,a
合并(a)696和a.post_id<746

MERGE(a)在执行这类查询以创建关系时,您可能无法逃避漫长的执行时间,而在只有ID和外键的情况下设置关系可能需要时间。也就是说,这里有很多改进的机会

特别有问题的是,您必须在:facebook-like-comment\u-id上执行toInt(),这意味着您不能利用这里的索引。您可以在您的配置文件中看到,笛卡尔乘积之后的过滤操作,它的命中率为3.72亿db;为了进行id比较,它必须迭代每一个:FacebookLike,将id更改为int,然后进行比较。这是查询中最昂贵的部分

如果:FacebookLike注释\u id已经是一个int(即,如果不需要toInt(),而您错误地将其留在了中),或者如果您花了一些时间将每个:FacebookLike注释\u id提前更改为int,那么您应该会看到该过滤器中的显著改进

这也是假设您同时在:FacebookComment.post_id和:FacebookLike.comment_id上创建索引(另外,确保您使用的字段正确……您的查询中有post_id、comment_id和id,可能很容易混淆)

至于其他改进(在解决了上面的大问题之后),将查询分解为多个部分将有助于避免笛卡尔积

完整查询可能如下所示:

MATCH (a:FacebookComment)
WHERE a.post_id > 696
AND a.post_id < 746 
WITH a
MATCH (b:FacebookLike)
WHERE b.comment_id = a.id
WITH a, b
CREATE (a)<-[fpl:FB_COMMENT_LIKE]-(b)
匹配(a:FacebookComment)
其中a.post_id>696
和a.post_id<746
用一个
匹配(b:FacebookLike)
其中b.comment_id=a.id
用a,b

创建(a)您正在通过
b
笛卡尔积构建
a
。你需要它们之间的关系,而不是使用WHERE子句来匹配id。实际上,我是在WHERE子句的基础上建立FacebookLike和FacebookComment之间的关系。好的。他们的id上有索引吗?我相信在筛选过程中会用到where子句。你的对手仍然可能是笛卡尔积。您可能希望解释或分析查询以了解它在做什么,然后尝试包括注释和类似内容之间的关系(允许您删除WHERE中的显式id匹配谓词),并查看这是否会改进查询。一般来说,您应该在匹配中指定所需的关系,并避免使用典型的sql方式在ID或键上进行连接。请参阅我更新的问题。如果数据量很大,上述查询仍然没有价值。它仍然需要太多的时间来执行。你能用上面的查询运行一个概要文件,并用执行时间将它添加到你的描述中吗?以及与要在其上运行此操作的数据集有关的任何其他因素?是否计划最终在整个数据集上运行查询并创建所有关系?我尝试过这样做,但它持续了很长时间,最后出现
Error Undefined Error Undefined Error
消息。好的,改用EXPLAIN。它不会那么详细,但不需要完全执行。感谢您的回复,问题是我稍微更改了查询。我使用了
Return
而不是
CREATE
relationship,因此返回数据花费了太多时间。
PROFILE 
Match (a:FacebookComment), (b:FacebookLike) WHERE a.id = toint(b.comment_id) AND a.post_id > 696 AND a.post_id < 746 
MERGE (a)<-[fpl:FB_COMMENT_LIKE]-(b)
MATCH (a:FacebookComment)
WHERE a.post_id > 696
AND a.post_id < 746 
WITH a
MATCH (b:FacebookLike)
WHERE b.comment_id = a.id
WITH a, b
CREATE (a)<-[fpl:FB_COMMENT_LIKE]-(b)