为什么这里没有使用哈希索引?

时间:2018-02-06 14:13:28

标签: arangodb

我不明白为什么在我的情况下没有使用定义的哈希索引:

FOR a in products_en

FOR i in a.infos 

// This one works and uses the index:
    LET test = "6GK1411-5AB10"

// This one does not use the index:
//        LET test = i.name

    LET catalogs = (FOR c IN MallCatalog 
                            FILTER test IN c.accessoires.mlfbs
                            RETURN c.defaultURL
                    )

    RETURN LENGTH(catalogs)

在i.name中,始终只有一个字符串。 我也试过像LET test = TO_STRING(i.name)和其他愚蠢的东西这样的技巧,但没办法。因此,即使每个集合中有10.000个元素,此查询的运行时也会变得恐怖: - (

以下是解释信息,第一个是固定字符串示例:

Execution plan:
 Id   NodeType                    Est.   Comment
  1   SingletonNode                  1   * ROOT
  2   EnumerateCollectionNode     5809     - FOR a IN products_en   /* full     collection scan */
  3   CalculationNode             5809       - LET #7 = a.`infos`   /*     attribute expression */   /* collections used: a : products_en */
  4   EnumerateListNode         580900       - FOR i IN #7   /* list iteration */
 12   SubqueryNode              580900         - LET catalogs = ...   /* const subquery */
  6   SingletonNode                  1           * ROOT
 15   IndexNode                      5             - FOR c IN MallCatalog       /* hash index scan */
 10   CalculationNode                5               - LET #11 = c.`defaultURL`   /* attribute expression */   /* collections used: c :     MallCatalog */
 11   ReturnNode                     5               - RETURN #11
 13   CalculationNode           580900         - LET #13 = LENGTH(catalogs)       /* simple expression */
 14   ReturnNode                580900         - RETURN #13

Indexes used:
 By   Type   Collection    Unique   Sparse   Selectivity   Fields                           Ranges
 15   hash   MallCatalog   false    true         17.29 %   [     `accessoires.mlfbs[*]` ]   ("6GK1411-5AB10" in c.`accessoires`.`mlfbs`)

Optimization rules applied:
 Id   RuleName
  1   move-calculations-up
  2   move-filters-up
  3   remove-unnecessary-calculations
  4   move-calculations-up-2
  5   move-filters-up-2
  6   use-indexes
  7   remove-filter-covered-by-index
  8   remove-unnecessary-calculations-2

这里有一个非固定替代方案:

Execution plan:
 Id   NodeType                    Est.   Comment
  1   SingletonNode                  1   * ROOT
  2   EnumerateCollectionNode     5809     - FOR a IN products_en   /* full collection scan */
  3   CalculationNode             5809       - LET #7 = a.`infos`   /* attribute expression */   /* collections used: a : products_en */
  4   EnumerateListNode         580900       - FOR i IN #7   /* list iteration */
  5   CalculationNode           580900         - LET test = i.`name`   /* attribute expression */
 12   SubqueryNode              580900         - LET catalogs = ...   /* subquery */
  6   SingletonNode                  1           * ROOT
  7   EnumerateCollectionNode    10837             - FOR c IN MallCatalog   /* full collection scan */
  8   CalculationNode            10837               - LET #9 = (test in c.`accessoires`.`mlfbs`)   /* simple expression */   /* collections used: c : MallCatalog */
  9   FilterNode                 10837               - FILTER #9
 10   CalculationNode            10837               - LET #11 = c.`defaultURL`   /* attribute expression */   /* collections used: c : MallCatalog */
 11   ReturnNode                 10837               - RETURN #11
 13   CalculationNode           580900         - LET #13 = LENGTH(catalogs)   /* simple expression */
 14   ReturnNode                580900         - RETURN #13

Indexes used:
 none

Optimization rules applied:
 Id   RuleName
  1   move-calculations-up
  2   move-filters-up
  3   move-calculations-up-2
  4   move-filters-up-2

有人可以帮帮我吗? 提前致谢

1 个答案:

答案 0 :(得分:2)

报告的行为不适用于devel3.3。两个版本都优化了查询,如下所示:

arangod> gut()
Query string:
     FOR i in infos
         LET test = "6GK1411-5AB10"
         LET catalogs = ( FOR c IN MallCatalog
                         FILTER test IN c.accessoires.mlfbs
                         RETURN c.defaultURL
                        )
         RETURN LENGTH(catalogs)


Execution plan:
 Id   NodeType                  Est.   Comment
  1   SingletonNode                1   * ROOT
  2   EnumerateCollectionNode      0     - FOR i IN infos   /* full collection scan */
 10   SubqueryNode                 0       - LET catalogs = ...   /* const subquery */
  4   SingletonNode                1         * ROOT
 13   IndexNode                    1           - FOR c IN MallCatalog   /* hash index scan */
  8   CalculationNode              1             - LET #8 = c.`defaultURL`   /* attribute expression */   /* collections used: c : MallCatalog */
  9   ReturnNode                   1             - RETURN #8
 11   CalculationNode              0       - LET #10 = LENGTH(catalogs)   /* simple expression */
 12   ReturnNode                   0       - RETURN #10

Indexes used:
 By   Type   Collection    Unique   Sparse   Selectivity   Fields                       Ranges
 13   hash   MallCatalog   false    false       100.00 %   [ `accessoires.mlfbs[*]` ]   ("6GK1411-5AB10" in c.`accessoires`.`mlfbs`)

Optimization rules applied:
 Id   RuleName
  1   move-calculations-up
  2   move-filters-up
  3   remove-unnecessary-calculations
  4   move-calculations-up-2
  5   move-filters-up-2
  6   use-indexes
  7   remove-filter-covered-by-index
  8   remove-unnecessary-calculations-2


arangod> gugu()
Query string:
     FOR i in infos
         LET test = i.name
         LET catalogs = ( FOR c IN MallCatalog
                         FILTER test IN c.accessoires.mlfbs
                         RETURN c.defaultURL
                        )
         RETURN LENGTH(catalogs)


Execution plan:
 Id   NodeType                  Est.   Comment
  1   SingletonNode                1   * ROOT
  2   EnumerateCollectionNode      0     - FOR i IN infos   /* full collection scan */
 10   SubqueryNode                 0       - LET catalogs = ...   /* subquery */
  4   SingletonNode                1         * ROOT
 13   IndexNode                    1           - FOR c IN MallCatalog   /* hash index scan */
  8   CalculationNode              1             - LET #8 = c.`defaultURL`   /* attribute expression */   /* collections used: c : MallCatalog */
  9   ReturnNode                   1             - RETURN #8
 11   CalculationNode              0       - LET #10 = LENGTH(catalogs)   /* simple expression */
  3   CalculationNode              0       - LET test = i.`name`   /* attribute expression */   /* collections used: i : infos */
 12   ReturnNode                   0       - RETURN #10

Indexes used:
 By   Type   Collection    Unique   Sparse   Selectivity   Fields                       Ranges
 13   hash   MallCatalog   false    false       100.00 %   [ `accessoires.mlfbs[*]` ]   (i.`name` in c.`accessoires`.`mlfbs`)

Optimization rules applied:
 Id   RuleName
  1   move-calculations-up
  2   move-filters-up
  3   move-calculations-up-2
  4   move-filters-up-2
  5   use-indexes
  6   remove-filter-covered-by-index
  7   remove-unnecessary-calculations-2
  8   move-calculations-down

编辑:

此外,对于稀疏索引,预期会出现所描述的行为,因为测试的动态值无法证明 null。这就是为什么稀疏索引只能与修复值一起使用。