拥有以下结构的文档:
{
path: String,
enabled: Long,
disabled: null || Long,
// other fields...
}
我想通过路径前缀和某些数字与文档时间戳之间的数字关系的组合来查看文档:(伪代码)
SELECT e FROM entries
WHERE
e.path STARTS WITH "somePrefix"
AND e.enabled <= timestamp
AND (
e.disabled == null
OR timestamp < e.disabled
)
如果有的话,我将从哪个指数结构中获益最多?我应该在 enabled
字段上有一个非稀疏跳转列表索引 disabled
上的稀疏索引和 path
上的全文非稀疏索引吗? ArangoDB是否能够为这些类型的查询使用多个索引?我阅读了关于索引用法的文档页面,但我还不清楚 .
1 回答
如果过滤条件与逻辑或组合,则ArangoDB可以在同一集合上使用多个索引,并且索引满足或分支条件 .
对于您的查询,您有三个条件与逻辑组合,后者包含一个或 .
AQL中没有
STARTS WITH
谓词,但您可以使用以前缀bounds:e.path >= @lower && e.path < @upper
构造的范围查询 . 对于"somePrefix"
的搜索值,边界将转换为@upper
为"somePrefix", and
@lowerbeing
"somePrefiy"`(搜索值,最后一个字符增加1) .在
path
上创建跳过列表索引将使查询使用该索引 .包括
enabled
的搜索条件,到目前为止的组合条件是e.path >= @lower && e.path < @upper && e.enabled <= @timestamp
. 虽然可以在多个属性上创建跳转列表索引,但它不会在path
和enabled
上使用,但仅在path
上使用 . 颠倒索引属性的顺序(即enabled
首先,然后是path
)也无济于事,因为索引只能用于enabled
,而不能用于path
.通常,skiplist索引将用于可以产生连续范围的条件部分 . 如果最左边的索引属性用于相等比较(例如
e.path == @path && e.enabled <= @timestamp
可以工作),那么就是这种情况,但如果它的最左边的索引属性是非等式比较(例如e.path >= @lower && e.path <= @upper
或@e.enabled <= @timestamp
),那么它将不会看到它的进一步索引属性,因为它无论如何都会产生一个非连续的范围 .还可以选择在
disabled
上创建跳过列表索引 . 这允许优化器在e.enabled <= @timestamp && (e.disabled == null || @timestamp < e.disabled)
部分使用该索引 . 它可以将其转换为e.disabled == null || @timestamp < e.disabled
,但这看起来并不是很有选择性 .总结:对于该特定查询,似乎没有一个好的索引选择 . 如果你能以某种方式将
STARTS WITH
更改为相等比较,那么你可以在path
和enabled
上创建一个组合的跳转列表索引,它可能是相当有选择性的 . 如果STARTS WITH
前缀总是大小相同,则可能值得将前缀保存在额外属性中,该属性可以编入索引而不是原始值,并使用相等比较进行查询:e.pathPrefix == @prefix && e.enabled <= @timestamp
. 这需要为每个文档保存和维护额外的前缀属性,但是在启用更多选择性索引时可能值得 .