neo4j cypher

上周,我花了很多时间来尝试优化大约20个使用实时系统数据执行的灾难性的Cypher查询(36866ms至155575ms)。 经过一番尝试和错误,以及来自Michael的大量投入,我能够大致确定对查询进行哪些操作才能使它们性能更好-最后,性能最差的查询降至521ms。冷图和1GB堆空间(并且该查询具有可选路径-不确定如何改进),其余都在50ms以下-与原始数字相比有很大改进。

希望这可能对其他人有所帮助,这就是我所做的事情(大多数是猜测工作,并且在很大程度上是不科学的)-也许Michael可以帮助解释内部原理,并根据某些假设对我进行纠正。 我要做的第一件事是确保每个密码查询都使用参数-如Neo4j文档中所述 ,这有助于缓存执行计划。

其次,我在Neo4j邮件列表中碰到了一个帖子,迈克尔在其中提到不重新实例化ExecutionEngine,以便上述参数化查询实际上可以缓存。 对于许多人来说,这似乎很明显,但这是一个容易被忽视的事实,因为我有一个名为QueryExecutor的类,该类包含一个执行带有参数映射的查询的方法,并且该方法为每个查询创建了一个新的ExecutionEngine。 一旦编写并多次使用了此方法,就很容易忘记。 但是,这是影响整体性能的一个非常重要的因素(文档中的提及将非常有帮助),它解释了为什么即使在参数化的情况下,我的查询通常也需要花费相同的时间来执行。 将其更改为使用缓存的ExecutionEngine,可以看到我的查询时间工作表的下半部分下降了……在缓存之后0到1毫秒-取得了出色的进展。

现在,要开始每个查询,从最坏的情况开始。 我决定在仅分配1GB堆空间的本地计算机上和冷图上进行优化。 因此,我忽略了缓存后查询执行的改进-我认为这是确保进度的一种更好的方法-如果第一个查询命中没有改善,那么您确实没有对其进行优化。 这样,如果它在有限的硬件上确实可以很好地工作,我对它在生产中可以更好地工作充满信心。

除了在代码中安排查询时间之外,我还使用webadmin控制台进行了优化。 该查询糟糕的指标是它不会返回并且控制台将挂起。 优化以使其不会挂起本身就是一个重大改进。 高度不科学,但我建议这样做。

我的第一个查询平均大约为76558ms(该时间是通过在引擎execute方法周围添加开始时间和结束时间而获得的)。 第一次优化后,它减少到466ms。 这是原始查询: https : //gist.github.com/4436272

这是经过优化的一个: https ://gist.github.com/4436281不需要执行此巨大匹配只是为了基于a的alertDate属性过滤出结果,因此我减少了匹配以返回最小的集合首先可以过滤的数据,即 通往的道路
如果要在第一次匹配之前执行错误查询,则会看到返回2万行之类的信息。 过滤后,它们只有450个奇数行。 可以想象,第二个查询Swift减少了可能要使用的结果数量。

第二个变化是我那天从迈克尔那里学到的东西,当时我问做大型比赛还是继续修剪子查询是否有意义。 他的回答是:“ 问题是,您是在使用match来通过描述模式来实际扩展结果集,还是只是要确定是否存在某些关系(也称为“过滤”)。 如果是后者,则可能要在where子句中使用path-expression语法。

WHERE a-[:FOO]->b
or WHERE NOT(a-[:FOO]->b)'

这花了一点时间来适应,因为我编写MATCH子句的方式恰恰是我脑子里的想法,但是现在我可以区分出所需结果的匹配项与过滤器的匹配项了。 在上面的查询中,我的结果中需要(ir),因此无需在匹配中包含(a)-[:alert_for_inspection]->(i); 我可以在WHERE中使用它来确保a确实与i有关。

这是另一个示例: https : //gist.github.com/4436293

立刻,您会看到我们按日期过滤了厘米关系-如果它们不在日期范围内,则无需我们先进行匹配。 因此,查询的这一部分可以重写为:

start c=node:companies(id={id})
match c <-[parent_company*0..]-(n)with n
match n-[:defines_business_process]->(bp)-[:has_cycle]->(cm)
where cm.measureDate>={measureStartDate} and cm.measureDate<={measureEndDate}

在那之后,下一个过滤器是相同的:

with cm
match (cm)-[:cycle_metric] ->m-[:metric_activity] ->ma-[:metric_unit] -> (u)-[:alert_for_unit]-(a) where a.alertDate=cm.measureDate and a.fromEntityType={type}

这进一步修剪了我们的结果集。 最后,将连接添加到r(以得到我们的结果),确保没有导致r产生但必不可少的路径进入WHERE子句:

with a,ma
match (r) < - [:for_inspection_result]-a-[:alert_for_inspection]- > i
where (i) < -[:metric_inspection]-(ma)
return a.id as alertId, r.value as resultValue

这是完整的查询: https ://gist.github.com/4436328原始时间-33360毫秒,优化后-246毫秒。

至少对我来说,我的大多数查询都属于这种模式,所以到第二天,我就能够非常快速地重构它们。 有趣的是,此后,我仍然感到响应缓慢,但是在日志中打印的查询时间很小。 消除之后,我发现我的代码在执行查询之后(由executionEngine.execute)实际上停留了很长时间,但是在结果集的第一次迭代中。我假设结果不一定在execute()方法期间收集,但是在结果集的迭代中比较懒惰-我不了解Cypher内部结构,因此我可能完全错了。 但是定时迭代本身可以指出更糟糕的查询。

其他点点滴滴-ORDER BY增加了很多时间。 如果没有它,那是您应该放弃的第一件事。 DISTINCT还增加了时间,但是在我的许多情况下,很难删除它。

如果要检查是否缺少可选路径,通常在哪里进行MATCH(u)-[r?:has_a]-(a)WHERE NOT(r为null),而是改写为MATCH(u)-[ other_stuff]-.. WHERE NOT(u-[:has_a] -a)的效果要好得多。 但是,在我有诸如MATCH X- [o?:optional] -Y WHERE(存在o,将Y匹配到A和B)或OR(不存在o,将X匹配到c和d)的可选路径的地方,我无法简化与没有可选路径的其他查询相比,这些查询仍需要一些时间。

最终-发现问题的时间太晚了,因为测试数据永远不会与实时数据非常接近。 图的结构起着很大的作用-一些节点是紧密连接的,而其他节点则不是那么重要-并且涉及那些紧密连接的节点的查询是对我们最大的伤害。 尽可能尝试使用生产质量数据进行性能测试,或者尝试创建与之类似的测试数据。

因此,总结一下:

  1. 始终参数化您的查询
  2. 缓存ExecutionEngine
  3. 找出您要过滤的内容,并尽早使用所涉及的匹配最少的过滤器,以便在进一步查询时结果集逐渐变小。 持续测量每个子查询中返回的时间和结果,以便您可以确定在过滤器不明显时首先执行的操作
  4. 检查您的MATCH和RETURN子句-在MATCH中仅包括RETURN所需的那些部分。 剩下的将用于过滤结果的信息可以进入WHERE
  5. 如果您不需要ORDER BY,请昨天放下
  6. 如果您不需要DISTINCT,也要摆脱它
  7. 如果不需要基于可选路径的检查,可以将检查是否存在可选路径从MATCH移到WHERE中
  8. 不仅要花费查询的execute(),还要花费时间迭代结果
  9. 如果您的Webadmin控制台挂起,则说明您做的不好。 删除查询的各个部分以找出有问题的部分。
  10. 尝试尽可能使用实时数据
  11. 在资源不佳的冷图上进行测试-当您看到生产中的图形滑过您时,您会感觉好多了!

参考: Thought Bytes博客上来自我们JCG合作伙伴 Aldrin和Luanne Misquitta的优化Neo4j Cypher查询 。

翻译自: https://www.javacodegeeks.com/2013/01/optimizing-neo4j-cypher-queries.html

neo4j cypher

neo4j cypher_优化Neo4j Cypher查询相关推荐

  1. Neo4j图数据库使用Cypher查询图形数据

    原文出处:http://www.yund.tech/zdetail.html?type=1&id=e5a7ca6d4e801e88790cc85b94e1f405 作者:jstarseven ...

  2. 优化Neo4j Cypher查询

    上周,我花了很多时间尝试使用实时系统中的数据来优化大约20个执行失败的Cypher查询(36866ms至155575ms). 经过一番尝试和错误,以及来自Michael的大量投入,我能够大致确定对查询 ...

  3. Neo4j图形数据库的一些基本Cypher查询指令总结

    1 Cypher查询语言简介 2 一些常用语句 2.1 批量创建导入节点 2.2 查看节点 2.3 批量删除节点 2.4 批量创建导入节点间关系 2.5 查询节点间关系 2.6 批量删除节点间关系 2 ...

  4. neo4j图形数据库简介,基本查询(cypher基本语法)

    neo4j简介 图形数据库 环境变量配置(需要Java环境):NEO4J_HOME+文件目录 : Path里面:%NEO4J_HOME%\bin : 命令窗口输入·: neo4j console然后输 ...

  5. Neo4j常用Cypher查询语句

    Neo4j常用Cypher查询语句 作者:胡佳辉, CSDN博客:https://blog.csdn.net/gobitan [1] 查看图数据库中所有的标签 match (n) return dis ...

  6. 【独家】让你一次性掌握Neo4j性能优化秘籍的三大狠招

    作者| 西湖数据智能研究院高级研发工程师 无极 大千世界纷繁复杂,万物之间总会有千丝万缕的关系.随着现代商业社会的发展,事物的关联关系越发错综复杂,传统的关系存储已经不能满足我们的业务需求." ...

  7. cypher 查询语句

    1. 什么是Cypher Cypher是一种声明式图查询语言,表达高效查询和更新图数据库.Cypher是相对简单的查询语法,它让我们更关注业务领域问题. Cypher语言的关键字不区分大小写,但是属性 ...

  8. mysql慢时如何防止重复账户_如何进行mysql数据库的优化? --慢查询定位 --索引详解 -- 定时备份...

    mysql数据库优化的常见方法: 1.表的设计要合理(满足3NF) 3范式 2.创建适当索引[主键索引|唯一索引|普通索引|全文索引|空间索引] 3.对SQL语句优化---->定位慢查询(exp ...

  9. 【一起去大厂系列】什么是回表查询?怎么优化回表查询?

    提到什么是回表查询之前,不得不先解释一下InnoDB的索引. InnoDB的索引 InnoDB有两大类索引,一类是聚集索引(Clustered Index),一类是普通索引(Secondary Ind ...

最新文章

  1. java final 接口_Java自学-接口与继承 final
  2. 反射得到父类的私有字段
  3. 九度OJ 朋友圈 并查集
  4. naarray查询 swift_数据分析库之Numpy
  5. ansys流固耦合分析与工程实例模型文件_平板射流冲击流固耦合分析
  6. Two-Stream RNN/CNN for Action Recognition in 3D Videos-阅读笔记
  7. 单双号限行,今天是否绿色出行
  8. pkpm快速入门教程_PKPM快速入门教程.ppt
  9. Caffe学习3:Layer
  10. 《实施Cisco统一通信管理器(CIPT1)》一1.3 总结
  11. 自定义NodeJS-C++ Addons使用说明
  12. 2022年,你还要做开源软件么?
  13. mybase6.0.4的license key的生成方法
  14. 算术运算符——加号的多种和自增自减
  15. 建立“顾客购买图书”的活动图(使用泳道)
  16. 开涛的博客 spring
  17. 如何在信息不完备下进行快速决策?
  18. 超微服务器查型号,超微 云服务器
  19. discuz的php7版本
  20. 高精度定位理论及应用

热门文章

  1. 零配置 之 Spring注解实现Bean定义
  2. java反射 修改静态方法的值 setAccessible
  3. LinkedList 的实现原理浅析
  4. 【博客】csdn搬家到wordpress
  5. JQuery 表单校验
  6. Map的两种遍历方法
  7. 在idea 中添加和删除模块Module
  8. idea 写html js 热部署
  9. 华为荣耀20计算机,华为云电脑将停止服务/荣耀新机保护壳曝光/小米新机渲染图曝光...
  10. php事件编程,PHP相应button中onclick事件的案例分析