精华 【Neo4j查询优化系列】在ORDER BY中使用节点属性索引提高排序性能
发布于 3 个月前 作者 graphway 439 次浏览 来自 分享

在neo4j 3.5版本中,增加了对ORDER BY的优化,可以通过本地数据库索引(Native Index)提高排序效率。对于有百万或更多节点的集合,排序性能提高会很显著。

在查询中,若要利用这一特性,具体方法如下:

1、为节点属性定义本地索引: CREATE INDEX ON :LABEL(Property)

属性值的类型可以是任何基本类型,但是Point类型除外。

2、在Cypher查询中对建立索引的节点属性显式使用下面任何过滤条件之一:

  • 相等 =
  • 区间:> 或 <
  • STARTS WITH或ENDS WITH
  • 包含:CONTAINS 注意:过滤条件中必须包含有类型的,这样Cypher编译器才会查找是否有数据库索引可以使用。具体例子见下文。

3、在ORDER BY中对建立索引的节点属性进行排序。

如果Cypher编译器能够使用索引对ORDER BY进行优化,那么EXPLAIN时会看到相应的操作符(operator):

  • NodeIndexContainsScan
  • NodeIndexSeekByRange 而不会再看到Sort、Top操作符。

否则,只会看到在内存中排序相关的操作符:

  • Sort
  • Top

例子如下。模型是只包含一种标签Account的节点,其属性有acctid, acctNo, id和ifsc(无索引)。

// 查看已创建的索引 Indexes ON :Account(acctNo) ONLINE ON :Account(acctid) ONLINE ON :Account(id) ONLINE

// ------ 没有在ORDER BY中使用索引的例子 -------

// 条件#1不满足:ifsc属性没有索引 MATCH (n:Account) WHERE n.ifsc CONTAINS ‘00’ RETURN n ORDER BY n.ifsc

// 条件#2不满足:没有过滤条件,无法判断acctid类型 MATCH (n:Account) RETURN n ORDER BY n.acctid

explain1.jpg

// 条件#2不满足:exists()不支持 MATCH (n:Account) WHERE exists(n.id) RETURN n ORDER BY n.id DESC LIMIT 1

// 条件#3不满足:acctNo没有出现在WHERE子句中 MATCH (n:Account) WHERE n.id > 0 RETURN n ORDER BY n.acctNo

// ------ 在ORDER BY中使用索引得到优化的例子 -------

// 所有条件满足、id属性是整数类型,使用>比较符 MATCH (n:Account) WHERE n.id > 0 RETURN n ORDER BY n.id DESC

explain2.jpg

// 所有条件满足、acctid是字符串类型,使用STARTS WITH MATCH (n:Account) WHERE n.acctid STARTS WITH ‘000’ RETURN n ORDER BY n.acctid DESC LIMIT 1

进一步提示:如果ORDER BY中的节点属性不需要在过滤条件中出现,为了提高性能,也可以把该属性加入WHERE子句中,并保证其永远为TRUE。例如: // 本例中,n.id的值永远为正 MATCH (n:Account) WHERE n.id > 0 AND n.ifsc CONTAINS 'TT’ RETURN n ORDER BY n.id DESC

在线参考: https://neo4j.com/docs/cypher-manual/current/query-tuning/cypher-index-values-order/

回到顶部