与使用默认规划器

时间:2015-04-27 14:36:35

标签: performance neo4j cypher

我正在使用neo4j-2.2.1并使用Transactional Cypher Restful Endpoint进行查询。我正在尝试使用以下查询匹配电子邮件节点

match (e:Email) where e.email in ['gxxxxxxs@yyy.com'] return count(e);

“电子邮件”节点中的电子邮件属性对其具有唯一约束,因此会在其周围自动构建索引。当我使用{"statements": [{"parameters": {"emails": ["gxxxxxxs@yyy.com"]}, "statement": "match (c:Email) where c.email in {emails} return count(c)"}]}中的查询参数运行它时,上面的查询花了23秒,因为当我直接运行它而没有任何参数时只花了0.0134秒  {"statements": [{"statement": "match (c:Email) where c.email in ['gxxxxxxs@yyy.com'] return count(c)"}]}

我试图对其进行分析以查看查询是如何执行的,令我惊讶的是,参数化查询没有使用我期望它使用的唯一索引查找。

下面给出的剖析结果 -

非参数化查询的配置文件

  

{"陈述":[{"陈述":"简介匹配(c:电子邮件)c.email在[' gxxxxxxs@yyy.com& #39;]返回计数(c)"}]}

{"结果":[{"列":["计数(C)&#34],"数据":[{ "排":[1]}],"计划" {"根" {" operatorType":" EagerAggregation&# 34;," DbHits":0,"行":1," 版本":" CYPHER 2.2 &#34 ;,"键名":""" EstimatedRows":1.0000000000279299,"的规划器":" COST ""标识符":["计数(C)&#34],"的子":[{"的 operatorType& #34;:" NodeUniqueIndexSeek ""指数":":电子邮件(电子邮件)""行&#34 ;: 1," DbHits":1," EstimatedRows":1.00000000005586,"标识符":[" C&#34],"的子&# 34;:[]}]}}}],"错误":[]}

以0.0134048461914秒结束

参数化查询的配置文件

  

{"陈述":[{"参数":{"电子邮件":[" gxxxxxx@yyy.com"]}, "声明":"个人资料匹配(c:电子邮件)其中c.email在{电子邮件}中返回计数(c)"}]}   {"结果":[{"列":["计数(C)&#34],"数据":[{&#34 ;排":[1]}],"计划" {"根" {" operatorType":" EagerAggregation&#34 ;, " DbHits":0,"行":1," 版本":" CYPHER 2.2 ",& #34;键名":""" EstimatedRows":1384.8193022918188,"的规划器":" COST & #34;"标识符":["计数(C)&#34],"的子":[{" operatorType":&# 34;过滤"," LegacyExpression":"任何( - -INNER - - 在{电子邮件}中c.email == - -INNER - - )""行":1," DbHits":5114522," EstimatedRows":1917724.4999999998,"标识符& #34;:[" C&#34],"的子":[{"的 operatorType":" NodeByLabelScan &#34 ;,"标签":":电子邮件""行":2557261," DbHits":2557262," EstimatedRows&#34 ;:2556966.0"标识符":[" C&#34],"的子":[]}]}]}}}], "错误":[]}

完成时间为23.5868499279秒

有人可以帮助我理解为什么参数化的密码查询没有使用唯一索引搜索

2 个答案:

答案 0 :(得分:3)

这是自2.2+以来Cypher报告的错误。 (不使用带参数的索引)

https://github.com/neo4j/neo4j/issues/4357

您可以通过在 PLANNER RULE 前添加查询前缀来避免这种情况,以便使用之前的Cypher规划器并获得性能,直到修复错误。

PLANNER RULE MATCH (e:Email) where e.email IN {emails} RETURN count(e);

答案 1 :(得分:0)

对于参数化查询,Cypher引擎似乎没有推断出要使用的正确模式索引,因此正在进行扫描。通常,密码引擎需要通过查看MATCH子句和WHERE条件并使用该信息来查找有用的索引来推断图中的开始查询的位置。

您可以要求它使用USING的特定索引。所以如果您的Cypher查询是这样的

MATCH (c:Email) 
USING INDEX c:Email(email)
WHERE c.email in ['gxxxxxxs@yyy.com'] 
RETURN count(c)

您应该发现使用NodeUniqueIndexSeek执行查询。等价物是

{
    "statements": [{
        "parameters": {
            "emails": ["gxxxxxxs@yyy.com"]
        }, 
        "statement": "MATCH (c:Email) 
                      USING INDEX c:Email(email) 
                      WHERE c.email IN {emails} 
                      RETURN count(c)"
    }]
}

(为了可读性添加了换行符)