基本查询调优示例
我们将从一个基本示例开始,帮助您了解查询分析。以下示例将使用电影数据集。
让我们从导入数据开始
LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/query-tuning/movies.csv" AS line
MERGE (m:Movie {title:line.title})
ON CREATE SET m.released = toInteger(line.released), m.tagline = line.tagline
LOAD CSV WITH HEADERS FROM 'https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/query-tuning/actors.csv' AS line
MATCH (m:Movie {title:line.title})
MERGE (p:Person {name:line.name})
ON CREATE SET p.born = toInteger(line.born)
MERGE (p)-[:ACTED_IN {roles:split(line.roles,";")}]->(m)
LOAD CSV WITH HEADERS FROM 'https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/query-tuning/directors.csv' AS line
MATCH (m:Movie {title:line.title})
MERGE (p:Person {name:line.name})
ON CREATE SET p.born = toInteger(line.born)
MERGE (p)-[:DIRECTED]->(m)
查找汤姆·汉克斯:简单方法
假设我们要编写一个查询来查找汤姆·汉克斯。简单的方法是编写以下代码
MATCH (p {name:"Tom Hanks"})
RETURN p
该查询将找到汤姆·汉克斯节点,但随着数据库中节点数量的增加,它会变得越来越慢。
分析
我们可以分析该查询以找出它为何如此慢。
PROFILE MATCH (p {name:"Tom Hanks"})
RETURN p
阅读执行计划时,首先要记住的是您需要从下往上阅读。
从最后一行开始,我们首先注意到Rows
列的值似乎很高,因为数据库中只有一个名为Tom Hanks
的节点。如果我们看一下Operator
列,我们会发现使用了AllNodesScan
,这意味着查询计划器扫描了数据库中的所有节点。
向上移动到上一行,我们看到Filter
操作符,它将检查每个由AllNodesScan
传递的节点的name
属性。
这似乎是一种低效的查找Tom Hanks
的方法,因为我们查看了许多甚至不是人,因此也不是我们正在寻找的节点。
查找汤姆·汉克斯:第二次尝试
无论何时查找节点,我们都应指定一个标签,以帮助查询计划器缩小搜索范围。对于此查询,我们需要添加一个Person
标签。
MATCH (p:Person {name:"Tom Hanks"})
RETURN p
此查询将比第一个查询快,但随着我们数据库中人数的增加,我们会再次注意到查询速度变慢。
分析
我们可以再次分析该查询,以找出为何我们的查询仍然有点慢
PROFILE MATCH (p:Person {name:"Tom Hanks"})
RETURN p
这次最后一行上的Rows
值已减少,因此我们没有扫描以前扫描过的一些节点,这是一个好的开始。NodeByLabelScan
操作符表示我们是通过首先对数据库中的所有Person
节点进行线性扫描来实现这一点的。
完成此操作后,我们再次使用Filter
操作符扫描所有这些节点,比较每个节点的name
属性。
在某些情况下这可能是可以接受的,但如果我们要经常按姓名查找人员,那么如果我们在Person
标签的name
属性上创建索引,我们将看到更好的性能
CREATE INDEX ON :Person(name)
分析
让我们分析该查询,以了解为何此版本如此快
PROFILE MATCH (p:Person {name:"Tom Hanks"})
RETURN p
我们的执行计划已减少到一行,并使用Node Index Seek
操作符,该操作符执行模式索引查找以找到适当的节点。
此页面是否有帮助?