标签顺序会影响搜索时间吗?

Do labels order effects search time?

我正在使用 neo4j 2.1.7 最近我正在试验匹配查询,搜索具有多个标签的节点。我发现,通常查询

Match (p:A:B) return count(p) as number

Match (p:B:A) return count(p) as number

工作时间不同,尤其是在您有 200 万个节点 A 和 0 个节点 B 的情况下。 那么标签顺序会影响搜索时间吗?这个未来在任何地方都有记录吗?

Neo4j 在内部维护一个 labelscan 存储 - 这基本上是一个查找,可以快速获取所有带有定义标签的节点 A

在执行类似

的查询时
MATCH (n:A:B) return count(n)

labelscanstore 用于查找所有 A 节点,然后如果这些节点也带有标签 B,则对它们进行过滤。如果 n(A) >> n(B) 执行 MATCH (n:B:A) 效率更高,因为您只查找几个 B 节点并为 A.

过滤这些节点

您可以使用PROFILE MATCH (n:A:B) return count(n)查看查询计划。对于 Neo4j <= 2。1.x 根据您指定的标签顺序,您将看到不同的查询计划。

从 Neo4j 2.2 开始(在撰写此回复时里程碑 M03 可用)有一个基于成本的 Cypher 优化器。现在 Cypher 知道节点统计信息并用于优化查询。

例如,我使用以下语句创建了一些测试数据:

create (:A:B);
with 1 as a foreach (x in range(0,1000000)  | create (:A));
with 1 as a foreach (x in range(0,100)  | create (:B));

我们现在有100个B节点,1M个A节点和1个AB节点。 2.2中的两条语句:

MATCH (n:B:A) return count(n)
MATCH (n:A:B) return count(n)

产生完全相同的查询计划(因此具有相同的执行速度):

+------------------+---------------+------+--------+-------------+---------------+
|         Operator | EstimatedRows | Rows | DbHits | Identifiers |         Other |
+------------------+---------------+------+--------+-------------+---------------+
| EagerAggregation |             3 |    1 |      0 |    count(n) |                       |
|           Filter |            12 |    1 |     12 |           n | hasLabel(n:A) |
|  NodeByLabelScan |            12 |   12 |     13 |           n |            :B |
+------------------+---------------+------+--------+-------------+---------------+

由于只有少数 B 个节点,扫描 B 并过滤 A 的成本更低。智能密码,不是吗 ;-)