【发布时间】:2014-10-23 10:09:39
【问题描述】:
我目前正在使用 Neo4j 作为数据库和涉及一些硬关系发现的查询的项目,并且在运行性能测试后我们遇到了一些问题。
我们发现缓存正在疯狂地影响请求的时间(从 3000 毫秒到 100 毫秒左右)。两次执行相同的请求会导致一个非常慢,而第二个会更快。经过一番搜索,我们看到了预热方法,即预加载数据库中的所有节点和关系,查询如下:
match (n)-[r]->() return count(1);
激活缓存加上这个预热查询后,我们的查询时间大大减少了,但仍然没有查询两次、三次或四次相同查询的速度那么快。
所以我们继续测试和搜索信息,直到我们看到 Neo4j 也在以某种方式缓冲查询,以免每次都被编译(如果我是对的话,使用 Scala 编译器)。我以某种方式说,因为经过激烈的测试,我可以得出结论,Neo4j 正在“即时”编译查询。
让我举一个简单的例子来说明我的意思:
(数字是id属性)
如果我提出如下请求:
match (n:green {id: 1})-[r]->(:red)-[s]->(:green)<-[t]-(m:yellow {id: 7})
return count(m);
我要做的是查找节点1和节点之间是否存在连接。如您所见,我必须发现一堆节点和更重要的关系,并且编译过程看起来或多或少复杂,因为请求需要 1227 毫秒才能完成。如果我再次发出完全相同的请求,我会得到大约 5 毫秒的响应时间,足以通过性能测试。 Neo4j 或 Scala 编译器肯定也在缓冲密码查询。
在了解密码请求中有一个编译过程后,我更深入地开始只修改已经缓冲的请求的一部分。更改匹配的最后一个节点的标签或 id 参数也会产生延迟,但只有约 19 毫秒,仍然可以接受:
match (n:green {id: 1})-[r]->(:red)-[s]->(:green)<-[t]-(m:purple {id: 7})
return count(m);
但是,当我重新启动服务器时,进行预热并调整查询,使第一个节点(之前标记为 n)不匹配,查询将响应非常快,结果为 0,因此我可以推断不是所有查询都已解析,因为第一个节点不匹配,因此无需深入树中。
我也尝试了可选匹配,如果没有找到匹配则返回 null,但它也不起作用。
我想首先问一下,到目前为止,我在测试中所说的一切是否正确,如果不是,它实际上是如何工作的?其次,我应该怎么做(如果有办法)在服务器启动时缓存所有内容。不幸的是,项目的要求说查询应该执行良好,即使是第一个(并不是说真实场景有数千个关系和节点,使一切变慢),或者如果没有办法避免这种延迟。
【问题讨论】:
-
你有关于 :green(id), :red(id) 和 :purple(id) 的索引吗?
标签: performance caching neo4j cypher