Performance 尽管有索引,但Neo4j查询速度较慢
在这里,我试图找到所有Twitter用户,他们被某个组的任何成员跟踪或跟踪Performance 尽管有索引,但Neo4j查询速度较慢,performance,neo4j,cypher,Performance,Neo4j,Cypher,在这里,我试图找到所有Twitter用户,他们被某个组的任何成员跟踪或跟踪G: MATCH (x:User)-[:FOLLOWS]->(t:User)-[:FOLLOWS]->(y:User) WHERE (x.screen_name IN {{G_SCREEN_NAMES}} OR x.id IN {{G_IDS}}) AND (y.screen_name IN {{G_SCREEN_NAMES}} OR y.id IN {{G_IDS}}) RETURN t.id 但是对于
G
:
MATCH (x:User)-[:FOLLOWS]->(t:User)-[:FOLLOWS]->(y:User)
WHERE (x.screen_name IN {{G_SCREEN_NAMES}} OR x.id IN {{G_IDS}})
AND (y.screen_name IN {{G_SCREEN_NAMES}} OR y.id IN {{G_IDS}})
RETURN t.id
但是对于组G
I,有时有他们的屏幕名称,有时有他们的ID,因此上面的或子句。不幸的是,此查询运行时间很长,似乎永远不会返回
我在id
和screen\u name
上都有索引和约束:
Indexes
ON :User(screen_name) ONLINE (for uniqueness constraint)
ON :User(id) ONLINE (for uniqueness constraint)
Constraints
ON (user:User) ASSERT user.screen_name IS UNIQUE
ON (user:User) ASSERT user.id IS UNIQUE
如果我去掉了OR子句(例如,如果我碰巧拥有组G的所有屏幕名称或所有ID),那么查询运行得相当快
我正在Mac上使用neo4j-community-2.1.3。我的图形有286039个节点,所有节点都有User
标签
有什么改进的办法吗?否则,我将不得不将其分成4个查询,以获得所有可能的成员组合。这确实是一个更大的问题,因为我真的想跟踪一个用户在G-->用户-->G关系中出现的频率,如果计数分布在4个不同的查询中,我需要做很多额外的簿记
更新
我创建了一个与此相关的问题:
我最终使用了
MATCH (x:User) WHERE x.screen_name IN ["apple","banana","coconut"]
WITH collect(id(x)) as x_ids
MATCH (x:User) WHERE x.id in [12345,98765]
WITH x_ids+collect(id(x)) as x_ids
MATCH (y:User) WHERE y.screen_name IN ["apple","banana","coconut"]
WITH x_ids,collect(id(y)) as y_ids
MATCH (y:User) WHERE y.id in [12345,98765]
WITH x_ids,y_ids+collect(id(y)) as y_ids
MATCH (x:User)-[:FOLLOWS]->(t:User)-[:FOLLOWS]->(y:User)
WHERE id(x) in x_ids AND id(y) in y_ids
RETURN count(*) as c, t.screen_name,t.id
ORDER BY c DESC
LIMIT 1000
但这基本上代表了一种绕过neo4j没有使用索引的地方的黑客行为。我猜由于或
条件,查询没有使用索引,您可以通过在查询前面加上PROFILE
进行验证,然后在neo4j shell中运行它
如果没有索引使用的概念,可以将查询分为两部分。第一个获取用户ID的组合列表,而不是OR,我们对两个查询进行联合(每个查询使用索引查找):
在客户端,将节点ID列表用作下一个查询的参数:
MATCH (x:User)-[:FOLLOWS]->(t)-[:FOLLOWS]->(y)
WHERE id(x) in {ids} AND id(y) in {ids}
RETURN t.id
我故意删除了t
和y
的标签,假设您只能跟随User
而不能跟随其他类型的节点。这将删除不必要的标签检查 我猜由于或
条件的原因,查询没有使用索引,您可以通过在查询前面加上PROFILE
进行验证,然后在neo4j shell中运行它
如果没有索引使用的概念,可以将查询分为两部分。第一个获取用户ID的组合列表,而不是OR,我们对两个查询进行联合(每个查询使用索引查找):
在客户端,将节点ID列表用作下一个查询的参数:
MATCH (x:User)-[:FOLLOWS]->(t)-[:FOLLOWS]->(y)
WHERE id(x) in {ids} AND id(y) in {ids}
RETURN t.id
我故意删除了t
和y
的标签,假设您只能跟随User
而不能跟随其他类型的节点。这将删除不必要的标签检查 JnBrymn
这个查询怎么样
MATCH (x:User)
WHERE x.screen_name IN {{G_SCREEN_NAMES}} OR x.id IN {{G_IDS}}
WITH x
MATCH (x)-[:FOLLOWS]->(t:User)
WITH t
MATCH (t)-[:FOLLOWS]->(y:User)
WHERE y.screen_name IN {{G_SCREEN_NAMES}} OR y.id IN {{G_IDS}}
RETURN t.id
恩典与和平
吉姆
这个查询怎么样
MATCH (x:User)
WHERE x.screen_name IN {{G_SCREEN_NAMES}} OR x.id IN {{G_IDS}}
WITH x
MATCH (x)-[:FOLLOWS]->(t:User)
WITH t
MATCH (t)-[:FOLLOWS]->(y:User)
WHERE y.screen_name IN {{G_SCREEN_NAMES}} OR y.id IN {{G_IDS}}
RETURN t.id
恩典与和平
Jim这也不会使用索引。这也不会使用索引。