1

我正在使用 NEO4J 数据库进行“压力测试”。这没什么大不了的,但部分结果让我怀疑这项技术是否适合在线应用程序(或者我根本没有得到 Cypher)。

第一个测试是逐个节点添加

(1° node) -[:NEXT_FRAME]-> () -[:NEXT_FRAME]-> () -[:NEXT_FRAME]-> () -[:NEXT_FRAME]-> ... -[:NEXT_FRAME]-> (last node)

然后使用此查询检索整个路径

START n=node:Frame(node_id="0"), m=node:Frame(node_id="9000")
MATCH p=(n)-[:FRAME_NEXT*]->(m)
RETURN p
ORDER BY m.node_id DESC
LIMIT 1

请注意,当 时m.node_id == 2,查询需要约 100 毫秒。现在有大约 9000 个节点,最多可能需要 30 秒。我不是专家,但是时间太长了!我不认为 9K 节点应该有这么大的不同。

那么,我错过了什么?

干杯(和圣诞快乐)

编辑:

我正在使用 py2neo 并以这种方式计时查询:

    q_str = """
    START n=node:Frame(node_id="0"), m=node:Frame(node_id="%d")
    MATCH p=(n)-[:FRAME_NEXT*]->(m)
    RETURN p
    ORDER BY m.node_id DESC
    LIMIT 1
    """ % (i,)
    print q_str

    before = datetime.datetime.now()
    query = neo4j.CypherQuery(graph_db, q_str)
    record, = query.execute().data
    after = datetime.datetime.now()
    diff = after - before
    diff_ms = diff.total_seconds() *1000
    print 'Query took %.2f ms' % (diff_ms)
4

3 回答 3

2

这是 Cypher 的一个缺点,它现在不能很好地处理长的可变长度路径。

你能试试MATCH p=shortestPath((n)-[:FRAME_NEXT*]->(m))吗?

另外,如果可以,您可以尝试 Neo4j 2.0,而不是使用旧索引,而是使用标签和新索引。根据查询计划,应该使用更快的双向遍历匹配器。

MATCH (n: Frame {node_id:"0"})-[:FRAME_NEXT*]->(m:Frame {node_id:"9000"})
RETURN p

或者使用 REST 遍历器可能会更好:http: //docs.neo4j.org/chunked/milestone/rest-api-traverse.html

或 REST-graph-algo: http ://docs.neo4j.org/chunked/milestone/rest-api-graph-algos.html

于 2014-01-03T02:45:18.457 回答
2

n该查询尝试识别 和 之间的每条路径m,这可能是一个巨大的数字,具体取决于图形的形状。

ORDER BY在这种情况下尽量避免。以下可能会更快,因为只需要识别一个路径:

START n=node:Frame(node_id="0"), m=node:Frame(node_id="9000")
MATCH p=(n)-[:FRAME_NEXT*]->(m)
RETURN p
LIMIT 1

如果您正在寻找纯粹的性能,最好直接使用遍历 API图形算法。这需要一些 Java 编码。

于 2013-12-26T11:28:29.417 回答
1

如果只有一条路径,您可以删除ODER BYLIMIT。还可以尝试使用该shortestPath函数,即使您的图中只有一个匹配路径(即即使所有路径都是最短的),它也可以更快。最后,如果您知道可变深度关系有多深,请在您的模式中声明它,如果您只知道粗略的深度,则指定一个范围。尝试将这些组合进行比较,您可以在 neo4j-shell 中分析它们并查看执行计划。

MATCH p=(n)-[:FRAME_NEXT*9000]->(m)
MATCH p=(n)-[:FRAME_NEXT*8900..9100]->(m)
MATCH p=shortestPath( (n)-[:FRAME_NEXT*]->(m) )
MATCH p=shortestPath( (n)-[:FRAME_NEXT*8900..9100]->(m) )
于 2014-01-02T14:31:00.577 回答