代码之家  ›  专栏  ›  技术社区  ›  Cassie

匹配多个表优化Neo4j

  •  -1
  • Cassie  · 技术社区  · 8 年前

    我在Neo4j数据库中有3个带有标签的节点——应用程序、电话簿、短信。 然而,我编写的查询执行了一段时间,并因一个关于堆减少的错误而崩溃。 如何优化我的查询?

    MATCH (pcb:PhoneContactsBook {phone: pcb.phone})-[:APP_PCB]->
          (a:Applications)-[:APP_SMS]->
          (sms:Sms {address: sms.address}) 
    RETURN distinct pcb.phone, 
           collect(a.application_id);
    

    我试图在用于过滤的字段(比如sms.address)上设置索引,但它们的运行时间更长。

    以下是查询计划: enter image description here

    1 回复  |  直到 8 年前
        1
  •  2
  •   cybersam    8 年前

    正如@stdob所指出的,以下两种节点模式 MATCH 条款没有任何意义(很可能是导致您坠机的原因):

    (pcb:PhoneContactsBook {phone: pcb.phone})
    
    (sms:Sms {address: sms.address}) 
    

    第一个节点模式是查找 PhoneContactsBook 节点谁的 phone 值等于自身,第二个节点模式正在寻找 Sms 节点谁的 address 价值等于自身。因为这些模式将匹配所有 电话联系簿 和 短讯服务 节点(只要有 电话 和 住址 属性),您的 火柴 子句最终执行了以下代码段的一个更昂贵的版本,它根本不按电话号码或地址进行过滤:

    MATCH (pcb:PhoneContactsBook)-[:APP_PCB]->(a:Applications)-[:APP_SMS]->(sms:Sms)
    

    因此,您的查询可能会导致大量匹配,这需要很长时间,并最终导致数据库耗尽堆。

    您没有提供足够的数据模型信息,我无法知道如何解决此问题。然而,如果我正确地假设 电话联系簿 节点包含一个 住址 财产,以及 短讯服务 节点包含一个 电话 财产,也许你的意思是:?

    MATCH (pcb:PhoneContactsBook {phone: sms.phone})-[:APP_PCB]->
          (a:Applications)-[:APP_SMS]->
          (sms:Sms {address: pcb.address}) 
    RETURN distinct pcb.phone, 
           collect(a.application_id);
    

    顺便说一下,你应该使用正确的术语。因为neo4j是一个图形数据库,所以它没有“表”。相反 Applications , 电话联系簿 和 短讯服务 是节点“标签”。

    推荐文章