2015-09-15 9 views
3

Я недавно обновил neo4j с 2.1.7 до 2.2.5. Я выяснил, что запросФункция Neo4j или ошибка с поисковым запросом?

Match (c:C) where id(c) = 111 with c Match (p:I{id: c.id}) return count(p) 

работал хорошо в 2.1.7, но она выполняет очень бедных в 2.2.5 (в 100 раз больше). У меня есть все необходимые индексы. Я изменил этот запрос

Match (c:C) where id(c) = 111 with c.id as c_id Match (p:I{id: c_id}) return count(p) 

и после этого он отлично работает в 2.2.5 Это два запроса имеет различный профиль. Но я не очень опытен профилированием.

ОБНОВЛЕНО Еще одна странная вещь: если я использую объяснение вместо профиля - он работает быстро.

neo4j-sh (?)$ PROFILE Match (c:C) where id(c) = 10563822 with c Match (i:I{id: c.id}) return count(i); 
==> +----------+ 
==> | count(i) | 
==> +----------+ 
==> | 4551  | 
==> +----------+ 
==> 1 row 
==> 18257 ms 
==> 
==> Compiler CYPHER 2.2 
==> 
==> Planner COST 
==> 
==> EagerAggregation 
==> | 
==> +Filter(0) 
==>  | 
==>  +CartesianProduct 
==>  | 
==>  +Filter(1) 
==>  | | 
==>  | +NodeByIdSeek 
==>  | 
==>  +NodeByLabelScan 
==> 
==> +------------------+---------------+---------+---------+-------------+-------------------------+ 
==> |   Operator | EstimatedRows | Rows | DbHits | Identifiers |     Other | 
==> +------------------+---------------+---------+---------+-------------+-------------------------+ 
==> | EagerAggregation |   26 |  1 |  0 | count(i) |       | 
==> |  Filter(0) |   652 | 4551 | 2522988 |  c, i |   i.id == c.id | 
==> | CartesianProduct |   6521 | 1261494 |  0 |  c, i |       | 
==> |  Filter(1) |    0 |  1 |  1 |   c |      c:C | 
==> |  NodeByIdSeek |    1 |  1 |  1 |   c |       | 
==> | NodeByLabelScan |  1261494 | 1261494 | 1261495 |   i |      :I | 
==> +------------------+---------------+---------+---------+-------------+-------------------------+ 
==> 
==> Total database accesses: 3784485 

sh (?)$ PROFILE Match (c:C) where id(c) = 10563822 with c.id as c_id Match (i:I{id: c_id}) return count(i); 
==> +----------+ 
==> | count(i) | 
==> +----------+ 
==> | 4551  | 
==> +----------+ 
==> 1 row 
==> 64 ms 
==> 
==> Compiler CYPHER 2.2 
==> 
==> Planner COST 
==> 
==> EagerAggregation 
==> | 
==> +Apply 
==>  | 
==>  +Projection 
==>  | | 
==>  | +Filter 
==>  | | 
==>  | +NodeByIdSeek 
==>  | 
==>  +NodeIndexSeek 
==> 
==> +------------------+---------------+------+--------+-------------+---------------------+ 
==> |   Operator | EstimatedRows | Rows | DbHits | Identifiers |    Other | 
==> +------------------+---------------+------+--------+-------------+---------------------+ 
==> | EagerAggregation |    1 | 1 |  0 | count(i) |      | 
==> |   Apply |    1 | 4551 |  0 | c, c_id, i |      | 
==> |  Projection |    0 | 1 |  1 |  c, c_id |    c.id | 
==> |   Filter |    0 | 1 |  1 |   c |     c:C | 
==> |  NodeByIdSeek |    1 | 1 |  1 |   c |      | 
==> | NodeIndexSeek |    1 | 4551 | 4552 |   i |    :I(id) | 
==> +------------------+---------------+------+--------+-------------+---------------------+ 
==> 
==> Total database accesses: 4555 
+2

Существует несколько способов, подобных этому, когда ПЛАНИРОВАНИЕ ЗАТРАТА в Neo4j 2.2.x не использует индексы. Эти поведения удаляются в будущих выпусках, вы можете попытаться префикс вашего запроса ПРАВИЛОМ PLANNER, чтобы использовать индексы схемы. –

+0

Вы можете делиться своими профилями для обоих запросов? –

+0

Профили добавлены – Evgen

ответ

0

У меня нет достаточно знаний о Neo4j внутренностей знать, почему ваш запрос снижается (CartesianProduct шаг кажется красный флаг) в более поздних версиях, но здесь является логическим эквивалентом запроса, кажется, что он должен гораздо быстрее:

START c = node(111) 
MATCH (p:I { id: c.id }) 
RETURN count(p) 

Вот профиля:

+------------------+------+--------+----------------------------------------------------------+-----------------------+ 
|   Operator | Rows | DbHits |            Identifiers |     Other | 
+------------------+------+--------+----------------------------------------------------------+-----------------------+ 
|  ColumnFilter | 1 |  0 |             count(p) | keep columns count(p) | 
| EagerAggregation | 1 |  0 | INTERNAL_AGGREGATE51b25e53-027d-439b-9046-c1a2a6b0fe70 |      | 
|   Filter | 0 |  0 |              c, p |   p.id == c.id | 
|   NodeById | 0 |  0 |              c, p | Literal(List(111)) | 
|  NodeByLabel | 0 |  1 |              p |     :I | 
+------------------+------+--------+----------------------------------------------------------+-----------------------+ 

ПРИМЕЧАНИЕ: Это следует рассматривать как временное решение, так как START устарел, и я не знаю, как долго этот вид использования будет продолжать поддерживаться.