我的数据库目前包含3个文档集合,文档介于250k到1.5M之间。我设置了自己的文档_key
,并在几个顶级字段和列表(包含对其他键或(索引)字段的引用的列表)中添加了哈希索引。
集合A和C通过B有一个n:m的关系。我第一次看到的查询看起来像这样:
for a in collection_a
filter a.name != null
filter length(a.bs) > 0
limit 1
return {
'akey': a._key
, 'name': a.name
, 'cs': (
for b in collection_b
filter b.a == a._key
for c in collection_c
filter b.c == c._key
return c.name
)
}
这非常缓慢。我还尝试了其他方法,例如使中间for
成为for b in a.bs
(bs是collection_b文档的键列表)。
打印出上述查询的explain()
会产生巨大的成本,getExtra()
表示未使用任何索引:
{
"stats" : {
"writesExecuted" : 0,
"writesIgnored" : 0,
"scannedFull" : 6009930,
"scannedIndex" : 0
},
"warnings" : [ ]
}
另一种方法的工作速度和我预期的一样快:
for a in collection_a
filter a.name != null
filter length(a.bs) > 0
limit 1
return {
'akey': a._key
, 'name': a.name
, 'cs': (
for b in a.bs
return DOCUMENT(collection_c , DOCUMENT(collection_b, b).c ).name
)
}
但即使在这里,似乎也没有使用索引:
{
"stats" : {
"writesExecuted" : 0,
"writesIgnored" : 0,
"scannedFull" : 3000,
"scannedIndex" : 0
},
"warnings" : [ ]
}
可能已经解释过的一点是,哈希索引不适用于列表的元素(或者我在创建它时犯了错误)?第二个例子的getExtras()
会暗示这一点。
然而,我的期望是arangodb索引列表的所有元素(例如a.bs
),并且查询优化器应该意识到在查询中使用了索引属性。
如果我运行for b in collection_b filter b.a == 'somekey'
,我会得到预期的即时结果。而这只是孤立地运行中间for
。当我单独运行最里面的for
时,行为相同。
这是一个错误吗?这种行为有解释吗?我在第一个查询中做错了吗? AQL示例本身使用嵌套的for
s,这是我自然最终尝试的结果。
答案 0 :(得分:2)
这已在版本2.3.2中修复。
澄清:您发布的查询是正确的。版本2.3.0中存在一个问题,该问题阻止了子查询中的索引被使用。 此问题已在2.3.2版中得到修复。 您发布的初始查询应正确使用2.3.2中的索引。如果连接属性上有可用的哈希索引,则应使用它,因为查询仅包含相等查找。