查询调优
Neo4j 旨在尽可能快地执行查询。然而,在优化以获得最大查询执行性能时,根据对领域和应用程序的了解来重写查询可能会有所帮助。
本页面包含有关如何使用不同策略来调优查询的信息。
有关更改查询运行时(runtime)的信息,请参阅关于 Cypher® 运行时概念的页面。
查询选项
查询执行可以通过使用查询选项进行微调。
为了使用这些选项中的一个或多个,必须在查询前加上 CYPHER,后跟查询选项,示例如下:
CYPHER query-option [further-query-options] query
有关 Cypher 中可用各种运行时的信息,请参阅 Cypher 运行时。
Cypher 规划器
Cypher 规划器接收一个 Cypher 查询并计算出一个能够解决该查询的执行计划。对于任何给定的查询,可能存在多个执行计划候选,每个候选以不同的方式解决该查询。规划器使用搜索算法来找到预估执行成本最低的执行计划。
下表描述了可用的规划器选项:
| 查询选项 | 描述 | 默认 | ||
|---|---|---|---|---|
|
使用基于成本的规划,并对计划搜索空间和时间设置默认限制。 |
|
||
|
|
|||
|
使用基于成本的规划,不对计划搜索空间和时间进行限制,以执行对最佳执行计划的穷举搜索。
|
Cypher 连接组件规划器已弃用
Cypher 规划器的一部分负责将独立模式的子计划组合成更大的计划——这项任务被称为连接组件。
下表描述了连接组件规划器的可用查询选项:
| 查询选项 | 描述 | 默认 | ||
|---|---|---|---|---|
|
在组合子计划时使用贪心方法。
|
|||
|
在组合子计划时使用基于成本的 IDP 搜索算法。
|
|
|
Cypher 查询选项 |
Cypher 更新策略
此选项影响更新查询的急切程度(eagerness)。
可选值包括:
| 查询选项 | 描述 | 默认 |
|---|---|---|
|
更新查询在需要时会被急切执行。 |
|
|
更新查询始终会被急切执行。 |
Cypher 表达式引擎
此选项影响运行时如何评估表达式。
可选值包括:
| 查询选项 | 描述 | 默认 |
|---|---|---|
|
在需要时编译表达式并使用编译后的表达式引擎。 |
|
|
始终使用解释型表达式引擎。 |
|
|
始终编译表达式并使用编译型表达式引擎。 |
Cypher 算子引擎
此查询选项影响流水线运行时是否尝试为算子组生成编译代码。
可选值包括:
| 查询选项 | 描述 | 默认 |
|---|---|---|
|
在适用时尝试生成编译后的算子。 |
|
|
从不尝试生成编译后的算子。 |
|
|
始终尝试生成编译后的算子。 不能与 |
Cypher 解释型管道回退
此查询选项影响流水线运行时对于其不支持的算子的行为。
可用选项包括:
| 查询选项 | 描述 | 默认 | ||
|---|---|---|---|---|
|
等同于 |
|
||
|
如果计划包含流水线运行时不支持的任何算子,则选择另一个运行时来执行整个计划。 不能与 |
|||
|
执行计划的部分可以在另一个运行时上执行。仅允许某些算子在另一个运行时上执行。 不能与 |
|||
|
执行计划的部分可以在另一个运行时上执行。任何算子都被允许在另一个运行时上执行。设置此选项的查询可能会产生错误的结果或失败。 不能与
|
Cypher 重规划
将查询字符串转换为高效的执行计划是一项昂贵的操作。一旦获得查询的执行计划,它就会被放入缓存。如果再次执行完全相同的查询,则跳过规划步骤。相反,直接从缓存中获取执行计划。
“重规划”是指即使查询之前已被规划,也必须重新规划的情况。Cypher 重规划发生在以下情况:
-
当查询不在缓存中时。这可能是服务器首次启动或重启时、缓存最近被清除时,或者超出了
server.memory.query_cache.per_db_cache_num_entries限制时。 -
当时间超过了
dbms.cypher.min_replan_interval值,并且数据库统计信息的变化超过了dbms.cypher.statistics_divergence_threshold值时。 -
当缓存的查询计划包含已失效的通知时。考虑一个具有
01N50: Label does not exist通知的查询计划。在添加一个之前不存在的标签的节点并再次运行相同的查询后,需要对该查询进行重规划。
在某些情况下,Cypher 查询规划可能发生在非理想的时间。例如,当查询必须尽可能快且已有有效计划时。
|
重规划不会同时针对所有查询执行;它与运行查询在同一个线程中执行,并可能阻塞该查询。然而,重规划一个查询不会触发其他任何查询的重规划。 |
有三种不同的重规划选项可用:
| 选项 | 描述 | 默认 |
|---|---|---|
|
这是上述规划和重规划选项。 |
|
|
这将强制执行重规划,即使根据规划规则计划是有效的。一旦新计划完成,它将替换查询缓存中的现有计划。 |
|
|
如果已存在有效计划,即使规划规则通常规定应进行重规划,也将使用该计划。 |
replan 选项加在查询之前。
例如:
CYPHER replan=force MATCH ...
在混合工作负载中,可以使用 Cypher 的 EXPLAIN 命令强制重规划。这对于在已知的低负载时间安排那些规划成本高昂的查询的重规划非常有用。使用 EXPLAIN 将确保查询仅被规划而不被执行。
例如:
CYPHER replan=force EXPLAIN MATCH ...
在已知的高负载时期,replan=skip 可用于避免引入不必要的延迟峰值。
当在查询被规划时提交了模式更改,正在规划的查询将进行重规划。例如,删除索引是一种模式更改。模式更改可能使获取的执行计划失效或变得低效。查询将重新规划,而不是继续使用已获取的执行计划。Cypher 选项 replan 对因模式更改引起的重规划没有影响。
Cypher 推断模式部分
对于某些查询,规划器可以从图结构中推断出标签或类型等谓词,从而增强其估计每个算子将产生行数的能力。(有关算子和估计行数在查询执行计划中的作用的更多信息,请参阅理解执行计划 - 读取执行计划。)选项 inferSchemaParts 控制规划器推断谓词的程度。
| 选项 | 描述 |
|---|---|
|
不推断任何谓词。 |
|
关系类型被用于推断连接节点上的标签。对应最少节点数量的标签被用于预估行数。避免推断多个标签提高了具有多个依赖标签的节点(例如每个 |
如果未提供此查询选项,则将使用 Operations Manual → Configuration settings → dbms.cypher.infer_schema_parts 中设置的值。