ArangoDB AQL深度数组扫描优化:查询访问指定国家城市的客户
可读性优化方案
你现有的写法可以用AQL原生的ANY ... SATISFIES运算符简化,语义完全等价,可读性大幅提升,执行效率和原写法一致:
FOR target IN usertable FILTER ANY target.visited_places SATISFIES CURRENT.country == @country AND @city IN CURRENT.cities END LIMIT @limit RETURN target
这里把CONTAINS换成IN运算符也是为了更贴合语义,两者性能没有差异。
性能优化方案
方案1:保留现有数据结构,加嵌套数组索引
不需要修改数据模型,直接给嵌套的到访字段建持久化索引,就能让查询命中索引避免全表扫描,建索引语句在ArangoShell中执行即可:
db.usertable.ensureIndex({ type: "persistent", fields: ["visited_places[*].country", "visited_places[*].cities[*]"], name: "idx_visited_country_city" })
数据量在十万级以下时,这个方案性价比最高,改造成本几乎为零。
方案2:拆分数据模型为图结构(适合百万级以上数据)
如果数据量较大、查询QPS高,可以把到访记录拆为独立的边集合:
- 顶点集合
customer:存储客户customer_id、first_name等基础信息 - 边集合
visited:每条边对应一次到访记录,属性包含country、city,_from字段关联客户顶点ID
优化后的查询语句:
FOR visit IN visited FILTER visit.country == @country AND visit.city == @city LIMIT @limit RETURN DOCUMENT(visit._from)
给visited集合的country和city字段建普通持久化索引即可,查询效率比嵌套数组索引高20%左右,且后续扩展到访时间、停留时长等属性也更灵活。
内容的提问来源于stack exchange,提问作者3bst0r
相关产品推荐
相关产品推荐

