Neo4j慢?我一定做错了什么,请告诉我是什么。

3
我看到嵌入式Neo4j的性能结果有些不太可能,表面上比预期的慢了几个数量级,所以我认为我"做错了",尽管我没有做任何复杂的操作。
我正在使用最新的Neo4j嵌入式Python绑定(https://github.com/neo4j/python-embedded)。
from neo4j import GraphDatabase
db = GraphDatabase('/tmp/neo4j')

我已创建 1500 个具有简单属性的虚假产品:

fake_products = [{'name':str(x)} for x in range(0,1500)]

我从中提取出节点,并将其创建为子参考节点的连接部分:

with db.transaction:
    products = db.node()
    db.reference_node.PRODUCTS(products)

    for prod_def in fake_products:
        product = db.node(name=prod_def['name'])        
        product.INSTANCE_OF(products)

现在,我看到的代码几乎与文档中的代码完全相同:

PRODUCTS = db.getNodeById(1) 
for x in PRODUCTS.INSTANCE_OF.incoming: 
    pass

遍历这1500个节点在我的Macbook Pro上需要>0.2秒。什么鬼。 (编辑:我当然运行了这个查询很多次,所以在python绑定中至少不是冷缓存的问题)

我尝试增加到15K,它花费了2秒。我下载了Gremlin并发出了一个等效的查询来调查是neo4j还是python绑定的问题:

g.v(1).in("INSTANCE_OF")

..看起来第一次尝试需要大约2秒钟,而在第二次运行时似乎几乎立即完成。

有任何想法为什么会这么慢?我得到的结果肯定是我的错误之一。

1个回答

1
这是Neo4j懒加载数据并不进行任何预取操作。在第一次运行时,您会访问磁盘,在第二次运行时,缓存已经被预热,这就是您真正的生产场景。

谢谢你的回答,Peter。我假设我创建和连接数据的方式是正确的?但是关于你的回答——至少在Python绑定结果中,我看到的不是这样的——上述遍历多次运行所需的时间相同。 - Wojtek
那么,在Gremlin/Groovy/Java领域中它很快,但不适用于Python? - Peter Neubauer
啊,试图在OSX Lion上安装JPype失败了,想要重现它 :/ - Peter Neubauer
这是我关于neo4j/python-embedded的github页面和jakewins的回复的报告:https://github.com/neo4j/python-embedded/issues/15我认为我按照这里的说明成功安装了JPype: https://dev59.com/nV7Va4cB1Zd3GeqPI1dc - Wojtek
抱歉之前的回复有些愚蠢,我没有意识到按下回车键会发送评论,所以在我还没说完之前就被发送了 :)无论如何,感谢您的关注。一旦缓存热起来,在gremlin/groovy中查询15k个节点非常快,所以问题肯定出在python绑定上。我真的很想使用neo4j(和gremlin,但是python绑定似乎不允许)。现在我正在尝试一种方法,我的python Web应用程序连接到一个由jython托管的zeromq服务器套接字,该套接字调用一个groovy类来检索结果。可能很难维护,但我现在看不到其他办法。 - Wojtek
好的,我们对您的发现非常感兴趣,也许您可以贡献绑定代码库,以便日后由社区进行维护? - Peter Neubauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接