Обход графа ArangoDB без использования объединенного индекса - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть два запроса, которые, исходя из моего понимания, должны быть в основном одинаковыми.Один выполняет фильтр для моей коллекции ребер и работает очень хорошо, в то время как другой запрос выполняет обход графика на глубину 1 и работает довольно плохо из-за неиспользования правильного индекса.

У меня есть коллекция accounts, коллекция transfers и объединенный индекс для transfers._to и transfers.quantity.

Это запрос фильтра:

 FOR transfer IN transfers  
    FILTER transfer._to == "accounts/testaccount" && transfer.quantity > 100
    RETURN transfer

, который правильно использует объединенный индекс:

Execution plan:
 Id   NodeType            Est.   Comment
  1   SingletonNode          1   * ROOT
  6   IndexNode       18930267     - FOR transfer IN transfers   /* skiplist index scan */
  5   ReturnNode      18930267       - RETURN transfer

Indexes used:
 By   Type       Collection   Unique   Sparse   Selectivity   Fields                  Ranges
  6   skiplist   transfers    false    false        10.11 %   [ `_to`, `quantity` ]   ((transfer.`_to` == "accounts/testaccount") && (transfer.`quantity` > 100))

Optimization rules applied:
 Id   RuleName
  1   use-indexes
  2   remove-filter-covered-by-index
  3   remove-unnecessary-calculations-2

С другой стороны, это мой запрос обхода графа:

 FOR account IN accounts
     FILTER account._id == "accounts/testaccount"

     FOR v, e IN 1..1 INBOUND account transfers
         FILTER e.quantity > 100
         RETURN e

, который использует только _to из объединенного индекса для фильтрации входящих ребер, но не использует quantity:

Execution plan:
 Id   NodeType          Est.   Comment
  1   SingletonNode        1   * ROOT
  9   IndexNode            1     - FOR account IN accounts   /* primary index scan */
  5   TraversalNode        9       - FOR v  /* vertex */, e  /* edge */ IN 1..1  /* min..maxPathDepth */ INBOUND account /* startnode */  transfers
  6   CalculationNode      9         - LET #7 = (e.`quantity` > 100)   /* simple expression */
  7   FilterNode           9         - FILTER #7
  8   ReturnNode           9         - RETURN e

Indexes used:
 By   Type       Collection   Unique   Sparse   Selectivity   Fields                  Ranges
  9   primary    accounts     true     false       100.00 %   [ `_key` ]              (account.`_id` == "accounts/testaccount")
  5   skiplist   transfers    false    false            n/a   [ `_to`, `quantity` ]   base INBOUND

Traversals on graphs:
 Id   Depth   Vertex collections   Edge collections   Options                                   Filter conditions
  5   1..1                         transfers          uniqueVertices: none, uniqueEdges: path   

Optimization rules applied:
 Id   RuleName
  1   use-indexes
  2   remove-filter-covered-by-index
  3   remove-unnecessary-calculations-2

Однако, поскольку я хочу использовать графикОбход, есть ли способ правильно использовать этот объединенный индекс?

Редактировать: я использую ArangoDB 3.4.2

1 Ответ

0 голосов
/ 14 июня 2019

Центрированные по вершинам индексы (индексы, которые создаются на ребре и содержат свойства «_from» или «_to»), обычно используются в обходах, когда фильтрация выполняется на пути, а не на самом ребре.(при условии, что оптимизатор не найдет лучшего плана, конечно)

Итак, в вашем запросе попробуйте что-то вроде следующего:

FOR account IN accounts
 FILTER account._id == "accounts/testaccount"
   FOR v, e IN 1..1 INBOUND account transfers
   FILTER p.edges[*].quantity ALL > 100
RETURN e

Вы можете найти документы об этом типе индекса здесь

...