《Neo4j High Performance》by Sonal Raj ——索引与优化部分

Part 2 Querying and Indexing in Neo4j

翻译来自DeepL和百度翻译(理性参考)。

高级Cypher技巧

Cypher是一种高效的语言,不仅使查询更简单,而且 还致力于最大限度地优化结果生成过程。还有很多 在性能方面的优化,可以借助于与应用程序的数据领域有关的知识来实现。在用于重组查询的应用程序的数据域的帮助下,可以实现更多的性能优化。

查询优化

💡 方案:
**0.避免全局数据扫描:**优化查询性能的手动模式取决于开发者为减少遍历域和确保在结果中只获得基本数据所做的努力。全局扫描会搜索整个图,这对较小的图来说没有问题,但对大数据集来说就不行了。——>在图形和查询中使用标签可以帮助优化搜索 模式的搜索过程。

#错误示范 
START n =node(*)
MATCH (n)-[:KNOWS]-(m)
WHERE n.identity = "Batman"
RETURN m
#正确示范 
START n =node(*)
MATCH (n:superheroes)-[:KNOWS]-(m)
WHERE n.identity = "Batman"
RETURN m

💡 **1.编制索引和约束条件以加快搜索速度:**在图空间中的搜索可以被优化并使之更快 如果数据被编入索引,或者我们对其应用某种 的约束。这样一来,遍历就避免了多余的匹配,而直接进入所需的索引位置。直接进入到所需的索引位置。

#添加索引 
CREATE INDEX ON: superheroes(identity)
#添加约束 
CREATE CONSTRAINT ON n:superheroes
ASSERT n.identity IS UNIQUE

💡 **2.避免笛卡尔积生成:**在创建查询时,我们应该包括以某种方式连接的实体。使用不特定或不相关的实体最终可能会产生大量未使用或意外的结果。

#错误示范 
MATCH (m:Game), (p:Player)
#避免笛卡尔积 

MATCH ( a:Actor), (m:Movie), (s:Series)
RETURN COUNT(DISTINCT a), COUNT(DISTINCT m), COUNT(DISTINCTs)
#优化方式 
MATCH (a:Actor)
WITH COUNT(a) as actors
MATCH (m:Movie)
WITH COUNT(m) as movies, actors
MATCH (s:Series)
RETURN COUNT(s) as series, movies, actors

💡 **3.在MATCH中使用更多的模式,而不是WHERE:**建议在MATCH子句中保留大部分的模式。WHERE子句并不完全是为了模式匹配;相反,当与START和WITH一起使用时,它是用来过滤结果的。然而,当与MATCH一起使用时,它实现了对所述模式的约束。因此,当你将模式与MATCH部分一起使用时,模式匹配会更快。在找到起点之后–无论是通过使用扫描、索引还是已经绑定的点–执行引擎将使用模式匹配来找到匹配的子图。由于Cypher是声明性的,它可以改变这些操作的顺序。WHERE子句中的谓词可以在模式匹配之前、期间或之后被评估。

💡**4.进一步拆分MATCH模式:**与其在同一个MATCH语句中以逗号分隔的方式出现多个匹配模式,你可以在几个不同的MATCH语句中分割这些模式。这个过程大大减少了查询时间,因为它现在可以在每个连续的匹配阶段在较小的或减少的数据集上进行搜索。

💡**5.对查询进行剖析:**你可以在响应的配置文件中监控你的查询的处理细节,你可以通过PROFILE关键字实现,或者在提出请求时将配置文件参数设置为True。一些有用的信息可以以_db_hits的形式出现,告诉你一个实体(节点、关系或属性)被遇到了多少次。

💡**6.查询中的参数:**Cypher的执行引擎试图优化并将查询转化为相关的执行计划。为了优化用于这一任务的资源量,与字面意思相比,使用参数是首选。通过这种技术,Cypher可以重新利用现有的查询,而不是解析或编译基于字面的查询来建立新的执行计划。

图模型优化

有时,查询优化可以成为使用Neo4j提高应用程序性能的好方法,但你可以在定义数据库时加入一些基本的做法,这样可以使事情变得更简单,使用起来更快。

💡 方案:
**1.显式定义:**如果我们正在处理的图形模型包含组件之间的隐式关系。当我们以明确的方式定义这些关系时,可以实现更高的查询效率。这会导致更快的比较,但它也有一个缺点,即现在图形需要更多的存储空间,以便为所有出现的数据添加一个额外的实体。
显示定义示例

💡 **2.属性重构:**这是指在WHERE或MATCH子句中复杂的耗时操作可以直接作为属性包含在图的节点中的情况。这不仅节省了计算时间,导致查询速度大大加快,而且还导致了图数据库中更有组织的数据存储实践,以实现实用性。

索引

只有当你的查询中最常用的属性都有索引时,查询的性能才会得到优化。否则,如果Neo4j对一个属性进行了索引,而检索另一个属性的匹配需要遍历所有的节点,那么Neo4j就没有索引的效用。你可以将搜索中要用到的属性聚合成一个属性,并为其单独建立索引以提高性能。

目前,模式索引不支持在同一索引下对标签的多个属性进行索引。但是,你可以对同一标签下的节点的不同属性使用多个索引。索引会占用数据库的空间,所以当你觉得不再需要某个索引时,解除数据库对这种索引的负担是很好的。

索引效益和权衡

索引并不是免费的。由于底层的应用程序代码负责管理和使用索引,应该仔细考虑所遵循的策略。不适当的决定或索引中的缺陷会导致性能下降或不必要地使用磁盘存储空间。

在索引的权衡清单上,最重要的是索引结果会使用存储空间,也就是说,被索引的实体数量越多,磁盘使用量就越大。为数据创建索引基本上是创建小的查找图或表的过程,以允许快速访问图中的数据。因此,对于诸如INSERT或UPDATE这样的写操作,我们要写两次数据,一次是创建节点,另一次是将其写到索引映射中,索引映射中存储了一个指向创建节点的指针。

此外,随着索引数量的增加,插入和更新的操作将花费相当多的时间,因为与创建或更新实体相比,执行索引的操作几乎一样多。由于更新/插入现在需要修改该实体的索引,代码库自然会扩大,如果你对查询的时间进行剖析,插入一个有索引的节点的时间大约是插入没有索引时的两倍。

另一方面,索引的好处是查询性能得到了很大的提高,因为图中的大段内容被从搜索域中剔除了。
!!请注意,为了实现快速查询而将Neo4j生成的ID存储在外部并不是一个好的做法,因为这些ID可能会被修改。节点和关系的ID是一种内部表示方法,明确地使用它们可能会导致流程中断。

因此,对于不同的应用程序,索引场景会有所不同。与读取操作相比,那些需要更频繁更新或创建的操作应该轻度使用索引实体,而主要处理读取的应用程序应该大量使用索引来优化性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值