我开始用下面的查询:为什么我使用count()运行时,我的密码查询需要10倍的时间?
PROFILE
MATCH Base = (SBase:Snapshot {timestamp:1454983481.304583})-[:contains]->()
MATCH Prime = (:Snapshot {timestamp:1454983521.642284})-[PContains:contains]->(SPrimePackage)
WHERE NOT (SBase)-[:contains]->(SPrimePackage)
RETURN PContains
LIMIT 10
我得到 “在119毫秒5834次总DB命中”。该图正确显示了9个节点和8个连接它们的边。然后我运行一个几乎相同的查询,除了我,而不是返回计数(不同的()):
PROFILE
MATCH Base = (SBase:Snapshot {timestamp:1454983481.304583})-[:contains]->()
MATCH Prime = (:Snapshot {timestamp:1454983521.642284})-[PContains:contains]->(SPrimePackage)
WHERE NOT (SBase)-[:contains]->(SPrimePackage)
RETURN count(distinct(SPrimePackage))
LIMIT 10
这使得“在1771毫秒1382270次总DB命中”。结果是正确的:8.然而,为什么count(distinct())如此慢而且更昂贵?我应该以其他方式做这个吗?
我跑的Neo4j 2.3.1
编辑1
为了确保我比较苹果和苹果,并强调这个问题,这里是一对类似的查询和结果:
MATCH Base = (SBase:Snapshot {timestamp:1454983481.304583})-[:contains]->()
MATCH Prime = (:Snapshot {timestamp:1454983521.642284})-[PContains:contains]->(SPrimePackage)
WHERE NOT (SBase)-[:contains]->(SPrimePackage)
RETURN SPrimePackage
LIMIT 10
请注意,它在原始中返回“SPrimePackage”而不是“PContains”。结果是“在740毫秒中总共有5834次数据访问”。
下面是与 “计数()” 完全相同的查询:
MATCH Base = (SBase:Snapshot {timestamp:1454983481.304583})-[:contains]->()
MATCH Prime = (:Snapshot {timestamp:1454983521.642284})-[PContains:contains]->(SPrimePackage)
WHERE NOT (SBase)-[:contains]->(SPrimePackage)
RETURN count(SPrimePackage)
LIMIT 10
结果: “在2731毫秒1382270次总DB命中”。注意只有区别在于“count()”。直觉上,我希望“count()”可以添加一个统计步骤,但显然它的作用远不止于此。为什么“count()”会触发所有这些额外的工作?
计数不是问题,不同的是因为在大量命中时耗费时间。我认为你正在寻找的解决方案是基于路径的查询,但我不擅长这一点,我希望有人会给你你需要的。 – Supamiu
嗨@Supamiu感谢您的评论。如果我使用count()而不是count(distinct())运行查询,则会在1454毫秒内得到“1382270总分贝命中数”。然而,那么我的计数就不再是我想要的:3296.有趣的是,3296除以8,这是我正在寻找的答案。 – EdwardTeach
哦,我希望更好的结果没有明显的...尝试添加索引到timestamp属性。 – Supamiu