我有一个打开嵌入式数据库并在其上运行多个查询的程序。我正在使用一个ExecutionEngine并为每个查询重用它。只运行前3个查询,这是最简单的,但是,我不知道需要多长时间,因为我在大约1/2小时后停止了它,之后它只进行了2次查询。我之前遇到过Cypher在这个图表上运行缓慢的问题,但它从未如此糟糕。我正在使用API进行一些更复杂的查询,但我更倾向于使用Cypher,因为它们非常简单。我还有一些其他的查询,我想运行,基本上需要运行并返回大部分数据库,一些节点多次..我知道这不推荐,但我需要根据他们的关系布局 - 获取图中的每个节点都完全没用。该查询需要几天时间,按我要的速度进行。我对其他人认为“慢”(例如500毫秒)没有问题,b / c这不是实时应用程序,但20分钟过度。出了什么问题?我做错了什么?
我的数据库包含数百万个节点,并且至少包含多少个关系。 Neo4j应该能够轻松处理大图。为什么我会有如此疯狂的执行时间?
如果有人可以帮我这个(也许我的疑问都错了?),我真的很感激!
谢谢, BSG 以下是前三个查询共30分钟+的代码。它运行每一个并将结果(一个简单的计数)打印到文件。
ExecutionEngine eng = new ExecutionEngine(graphdb);
String filepath = resultstring + "basicstats.txt";
PrintWriter basics = new PrintWriter(resultstring + "basicstats.txt");
String querystring = "START user=node:userIndex(\"Username:*\")" +
" WHERE has(user.FullNodeCreationTime) "
+ " RETURN COUNT(user) AS numcrawled";
ExecutionResult result = eng.execute(querystring);
basics.print("Number of users crawled: ");
basics.println(result.iterator().next().get("numcrawled"));
String otherusers = "START user=node:userIndex(\"Username:*\")" +
" WHERE NOT has(user.FullNodeCreationTime)" +
" RETURN COUNT(user) AS numtouched";
result = eng.execute(otherusers);
basics.print("Number of users touched (not crawled): ");
basics.println(result.iterator().next().get("numtouched"));
String partialinfousers = "START user=node:userIndex(\"Username:*\")" +
" WHERE NOT has(user.FullNodeCreationTime) AND NOT has(user.NumFollowers)" +
" RETURN COUNT(user.Username) AS numcrawled";
result = eng.execute(partialinfousers);
basics.print("Number of users with partial info: ");
basics.println(result.iterator().next().get("numcrawled"));
basics.close();
答案 0 :(得分:0)
您的数据库有多大?您userIndex
中有多少用户?
您的内存/堆配置是什么?我假设您遇到了很多GC问题,因为Cypher试图将整个数据库整合到内存中以供查询。
此外,对于冷缓存和少量内存,您基本上可以测量磁盘速度以将数据拉入内存。
您可以将查询合并为一个。
START user=node:userIndex("Username:*")
RETURN has(user.FullNodeCreationTime),has(user.NumFollowers), COUNT(*) AS num
应该为4个组合返回4个条目,您可以轻松使用/聚合
所有这些都不是图形查询,也是图形全局查询。所以Neo4j和Cypher都没有针对他们进行优化:)
答案 1 :(得分:0)
首先,使用EXPLAIN从shell运行查询,以查看查询的运行方式。这是第一个开始了解性能问题的地方。
其次,如果我正确理解您的第一个查询,您只想知道有多少节点具有属性 FullNodeCreationTime 。您现有的查询并未以最佳方式使用索引,因为您没有查找特定值。它看起来好像您正在查看单个节点类型,这意味着具有特定标签的节点(如User)。如果这是正确的,那么我将在 User.FullNodeCreationTime 上创建一个索引,然后运行此查询:
match (u:User) where has (u.FullNodeCreationTime) return count(u)
那应该表现得更好。