Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4j使用OR运算符时性能不佳_Neo4j_Cypher_Graph Databases_Query Performance_Boolean Expression - Fatal编程技术网

Neo4j使用OR运算符时性能不佳

Neo4j使用OR运算符时性能不佳,neo4j,cypher,graph-databases,query-performance,boolean-expression,Neo4j,Cypher,Graph Databases,Query Performance,Boolean Expression,我使用的是neo4j-3.5社区版。我用neo4j构建了一个巨大的图形,其中包含了大约2000万个电影数据节点。我还插入了类型和关键字,并构建了图表。 以下查询需要>5秒 MATCH (p:`Program`), (p:Program)-[genre:of_genre]->(g:Genre), (p:Program)-[key_rel:associated_keyword]->(k:Keyword) WHERE ((g.id IN [

我使用的是neo4j-3.5社区版。我用neo4j构建了一个巨大的图形,其中包含了大约2000万个电影数据节点。我还插入了类型和关键字,并构建了图表。 以下查询需要>5秒

MATCH 
    (p:`Program`),  
    (p:Program)-[genre:of_genre]->(g:Genre), 
    (p:Program)-[key_rel:associated_keyword]->(k:Keyword)
  WHERE   
    ((g.id IN [1010]) OR (k.id IN ['keyword_121'])) AND 
    ((p.show_type IN ['movie'])) AND 
    (p.imdb_score > 0)
  RETURN distinct p.id, p.imdb_score
  ORDER BY p.imdb_score desc
  LIMIT 50
而如果我用AND替换或,则需要<100 ms

MATCH 
    (p:`Program`),  
    (p:Program)-[genre:of_genre]->(g:Genre), 
    (p:Program)-[key_rel:associated_keyword]->(k:Keyword)
  WHERE   
    ((g.id IN [1010]) AND (k.id IN ['keyword_121'])) AND 
    ((p.show_type IN ['movie'])) AND 
    (p.imdb_score > 0)
  RETURN distinct p.id, p.imdb_score
  ORDER BY p.imdb_score desc
  LIMIT 50
在类型id和关键字id上有索引

“或”的配置文件响应:

“和”的配置文件响应:


使用OR运算符编写查询是否有更好的方法?

您的查询在3个断开连接的模式之间构建笛卡尔乘积。

请尝试以下查询:

  MATCH 
    (k:Keyword)<-[key_rel:associated_keyword]-(p:Program)-[genre:of_genre]->(g:Genre)
  WHERE   
    ((g.id IN [1010]) OR (k.id IN ['keyword_121'])) AND 
    ((p.show_type IN ['movie'])) AND (p.imdb_score > 0)
  RETURN distinct p.id, p.imdb_score
  ORDER BY p.imdb_score desc
  LIMIT 50
匹配
(k:关键词)(g:体裁)
哪里
(g.id在[1010]中)或(k.id在['keyword_121']中)以及
((p.show_键入['movie'])和(p.imdb_得分>0)
返回不同的p.id、p.imdb_分数
按p.imdb_分数说明订购
限制50

您的查询在3个断开连接的模式之间构建笛卡尔乘积。

请尝试以下查询:

  MATCH 
    (k:Keyword)<-[key_rel:associated_keyword]-(p:Program)-[genre:of_genre]->(g:Genre)
  WHERE   
    ((g.id IN [1010]) OR (k.id IN ['keyword_121'])) AND 
    ((p.show_type IN ['movie'])) AND (p.imdb_score > 0)
  RETURN distinct p.id, p.imdb_score
  ORDER BY p.imdb_score desc
  LIMIT 50
匹配
(k:关键词)(g:体裁)
哪里
(g.id在[1010]中)或(k.id在['keyword_121']中)以及
((p.show_键入['movie'])和(p.imdb_得分>0)
返回不同的p.id、p.imdb_分数
按p.imdb_分数说明订购
限制50
这可能更适合您:

OPTIONAL MATCH (g:Genre) WHERE g.id IN [1010]
OPTIONAL MATCH (k:Keyword) WHERE k.id IN ['keyword_121']
WITH g, k
MATCH (p:`Program`)
WHERE
  p.show_type IN ['movie'] AND
  p.imdb_score > 0 AND
  ((p)-[:of_genre]->(g) OR (p)-[:associated_keyword]->(k))
RETURN distinct p.id, p.imdb_score
ORDER BY p.imdb_score desc
LIMIT 50
此查询可能同时使用这两个索引(或者至少您可以给出使用它们的方法)。此外,如果电影在数据库中不是很常见,您可能需要在
:Program(show_type)
上创建索引

WHERE
子句还只是测试是否存在一个所需的
:of_genre
:associated_关键字
关系——它不会尝试实际扫描并在内存中保存所有这些关系。

这可能对您更有效:

OPTIONAL MATCH (g:Genre) WHERE g.id IN [1010]
OPTIONAL MATCH (k:Keyword) WHERE k.id IN ['keyword_121']
WITH g, k
MATCH (p:`Program`)
WHERE
  p.show_type IN ['movie'] AND
  p.imdb_score > 0 AND
  ((p)-[:of_genre]->(g) OR (p)-[:associated_keyword]->(k))
RETURN distinct p.id, p.imdb_score
ORDER BY p.imdb_score desc
LIMIT 50
此查询可能同时使用这两个索引(或者至少您可以给出使用它们的方法)。此外,如果电影在数据库中不是很常见,您可能需要在
:Program(show_type)
上创建索引



WHERE
子句也只是测试是否存在一个所需的
:of_genre
:associated_关键字
关系——它不会尝试实际扫描并在内存中保存所有这些关系。

您能在开始时使用
配置文件运行查询并在此处共享扩展的计划吗?@Raj:我已经更新了配置文件输出的问题。很难说计划的哪个部分与查询的哪个部分相对应。请首先展开计划的所有元素(查看查询计划时,查询结果窗格右下角的双向下箭头),然后将其添加到问题中,替换您提供的折叠计划。@InverseFalcon:我已更新了查询的计划。您能否在开始时使用
PROFILE
运行查询,并在此处共享扩展的计划?@Raj:我已使用PROFILE输出更新了问题。很难判断计划的哪个部分与查询的哪个部分相对应。请首先展开计划的所有元素(查看查询计划时,查询结果窗格右下角的双向下箭头),然后将其添加到问题中,替换您提供的折叠计划。@InverseFalcon:我已经更新了查询计划。这仍然需要与以前类似的时间。@Raj我认为在
中没有必要使用
,我们可以使用equals运算符Used,以防需要与多个ID进行匹配。@sravan您可以在没有IN的情况下检查一次吗?@Govind Singh:我必须在中使用运算符。这仍然需要与以前类似的时间。@Raj我认为在
中没有必要使用中的,我们可以使用equals运算符或Used IN,以防需要与多个ID进行匹配。@sravan您可以在不输入的情况下检查一次吗?@Govind Singh:我必须在运算符中使用。此更改不会将性能提高到预期的性能~4秒变为~1.5秒。但是AND查询在100毫秒内执行。您不应该期望性能提高到那个水平。明白简单地改变或改变并不是简单的。它改变了查询必须执行的正确操作的逻辑。它不能只依赖于从
k
进行遍历,它必须完成从
g
进行遍历的工作,否则,如果使用AND,就不需要这些工作。必须做更多的工作,因为没有其他选择使其逻辑正确。您应该分析cybersam的查询。如果它在
k
g
上使用索引查找,那么它可能是您可以获得的最佳索引。此更改不会将性能提高到预期的性能~4秒变为~1.5秒。但是AND查询在100毫秒内执行。您不应该期望性能提高到那个水平。明白简单地改变或改变并不是简单的。它改变了查询必须执行的正确操作的逻辑。它不能只依赖于从
k
进行遍历,它必须完成从
g
进行遍历的工作,否则,如果使用AND,就不需要这些工作。必须做更多的工作,因为没有其他选择使其逻辑正确。您应该分析cybersam的查询。如果它在
k
g
上使用索引查找,那么它可能是您能得到的最好结果。