为什么我的Neo4J复合指数没有与MATCH和ORDER BY一起使用?

dbf7pr2w  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(139)

我有很多标签为Person的节点,属性为treeIdfirstNamelastName,我试图实现一个性能良好的所有Person的无限滚动,其中包含一些treeId,按字母顺序排列:

MATCH (p:Person {treeId: "admin"}) RETURN p ORDER BY p.lastName, p.firstName SKIP 100 LIMIT 20

**问题:**要使此操作尽可能多地在索引上运行,需要创建什么索引?

我尝试创建这样的索引:

CREATE INDEX personTreeLastNameFirstName FOR (p:Person) ON (p.treeId, p.lastName, p.firstName)

但是对于该索引,第一操作是NodeByLabelScan,因此不使用该索引。
我尝试的另一个索引更有帮助:

CREATE INDEX personTree FOR (p:Person) ON p.treeId

第一个操作在使用时是NodeIndexSeek,但它不包括姓名,因此需要从数据库中读取具有指定treeId的每个Person。
我需要创建什么索引,或者我需要如何重写查询,以使其在大量具有相同treeId的Person上更高效?

ljsrvy3e

ljsrvy3e1#

索引:

CREATE INDEX personTree FOR (p:Person) ON p.treeId

仅索引treeId,因此只能用于对treeIds进行排序和搜索。
综合指数:

CREATE INDEX personTreeLastNameFirstName FOR (p:Person) ON (p.treeId, p.lastName, p.firstName)

索引treeIdlastNamefirstName,但这里的陷阱是只有当所有三个索引键都出现在搜索子句中时,它才会被使用,这就是为什么你会得到NodeByLabelScan。为了允许neo4j使用你的复合索引,你应该为firstNamelastName添加一些搜索条件。

MATCH (p:Person) 
WHERE p.treeId= "admin" AND p.firstName > "" AND p.lastName > "" 
RETURN p 
ORDER BY p.lastName, p.firstName 
SKIP 100 LIMIT 20

相关问题