【发布时间】:2014-11-18 20:01:53
【问题描述】:
我有以下密码查询:
MATCH (country:Country { name: 'norway' }) <- [:LIVES_IN] - (person:Person)
WITH person
MATCH (skill:Skill { name: 'java' }) <- [:HAS_SKILL] - (person)
WITH person
OPTIONAL MATCH (skill:Skill { name: 'javascript' }) <- [rel:HAS_SKILL] - (person)
WITH person, CASE WHEN skill IS NOT NULL THEN 1 ELSE 0 END as matches
ORDER BY matches DESC
LIMIT 50
RETURN COLLECT(ID(person)) as personIDs
添加更多节点时性能似乎更差。现在只有 5000 个 Person 节点(一个 Person 节点可以与 Skill 节点有多个 HAS_SKILL 关系)。现在执行查询大约需要 180 毫秒,但是添加另外 1000 个具有关系的 Person 节点会为查询增加 30-40 毫秒。我们计划拥有数百万个 Person 节点,因此每 1000 个 Person 增加 40 毫秒是行不通的。
我在查询中使用参数,而不是在上述查询中使用“norway”、“java”、“javascript”。我在 :Country(name) 和 :Skill(name) 上创建了索引。
我的查询目标是匹配居住在指定国家(挪威)的每个人,这些人也具有“java”技能。如果此人还具有“javascript”技能,则应在结果中对其进行排序。
如何重组查询以提高性能?
编辑:
如果我切换出去,:Country 节点似乎也有问题
MATCH (country:Country { name: 'norway' }) <- [:LIVES_IN] - (person:Person)
与
MATCH (city:City { name: 'vancouver' }) <- [:LIVES_IN] - (person:Person)
查询时间会下降到大约 15-50 毫秒,具体取决于我查询的城市。添加更多节点时,查询时间仍然明显增加。
编辑 2:
当第一个匹配子句中有很多行时,我似乎查询时间增加了很多。因此,如果我先将查询切换为在技能节点上匹配,则查询时间会大大减少。该查询是 API 的一部分,它是动态创建的,我不知道哪个匹配子句将返回最少的行。当数据库增长时,每个匹配子句中的行数也可能会更多。
编辑 3
我已经对答案进行了一些测试,现在我有以下查询:
MATCH (country:Country { name: 'norway'})
WITH country
MATCH (country) <- [:LIVES_IN] - (person:Person)
WITH person
MATCH (person) - [:HAS_SKILL] -> (skill:Skill) WHERE skill.name = 'java'
MATCH (person) - [:MEMBER_OF_GROUP] -> (group:Group) WHERE group.name = 'some_group_name'
RETURN DISTINCT ID(person) as id
LIMIT 50
这仍然存在性能问题,首先匹配所有技能等是否更好,例如与 Country 节点?查询也可以变得更大,我可能需要添加针对多个技能、组、项目等的匹配。
编辑 4
我稍微修改了查询,似乎这成功了。我现在首先匹配所有需要的技能、公司、团体、国家等。然后在查询中稍后使用它们。在分析器中,这将数据库命中从 700k 减少到 188 或其他东西。它与我的原始查询(不同的标记节点等)略有不同,但它解决了相同的问题。我想这可以通过首先在具有最少关系的节点上匹配等来进一步改进,从减少节点数量开始。稍后我会进行更多测试!
MATCH (company:Company { name: 'relinkgroup' })
WITH company
MATCH (skill:Skill { name: 'java' })
WITH company, skill
MATCH (skill2:Skill { name: 'ajax' })
WITH company, skill, skill2
MATCH (country:Country { name: 'canada' })
WITH company, skill, skill2, country
MATCH (company) <- [:WORKED_AT] - (person:Person)
, (person) - [:HAS_SKILL] -> (skill)
, (person) - [:HAS_SKILL] -> (skill2)
, (person) - [:LIVES_IN] -> (country)
RETURN DISTINCT ID(person) as id
LIMIT 50
【问题讨论】: