在ArangoDB中,我有一个包含配置文件消息的图表。为了报告目的,我需要汇总过去12个月每个月特定类别消息的消息数量。
每个邮件的日期和类别位于配置文件和消息之间的每一个边缘。
目前,我有:
for mo in 0..11
let month = DATE_MONTH(DATE_SUBTRACT(DATE_NOW(),mo,"month"))
let msgCount = count(
for v, e in outbound "profileId" graph 'MyGraph'
filter e.category == "myCategory" && DATE_MONTH(e.date) == month
return 1
)
return {month: month, msgCount: msgCount}这个查询在超过1秒内执行,对于这个over应用程序来说,这有点慢,因为我需要为几个类别创建和可视化这个报告。
是否有任何优化能够更快地产生相同的结果?
发布于 2016-08-31 09:53:42
分析查询
使用db._explain()显示了以下内容:
Execution plan:
Id NodeType Est. Comment
1 SingletonNode 1 * ROOT
2 CalculationNode 1 - LET #7 = 0 .. 11 /* range */ /* simple expression */
3 EnumerateListNode 12 - FOR mo IN #7 /* list iteration */
4 CalculationNode 12 - LET month = DATE_MONTH(DATE_SUBTRACT(DATE_NOW(), mo, "month")) /* v8 expression */
11 SubqueryNode 12 - LET #4 = ... /* subquery */
5 SingletonNode 1 * ROOT
9 CalculationNode 1 - LET #11 = 1 /* json expression */ /* const assignment */
6 TraversalNode 1 - FOR v /* vertex */, e /* edge */ IN 1..1 /* min..maxPathDepth */ OUTBOUND 'profileId' /* startnode */ GRAPH 'MyGraph'
7 CalculationNode 1 - LET #9 = ((e.`category` == "myCategory") && (DATE_MONTH(e.`date`) == month)) /* v8 expression */
8 FilterNode 1 - FILTER #9
10 ReturnNode 1 - RETURN #11
13 CalculationNode 12 - LET #13 = { "month" : month, "msgCount" : COUNT(#4) } /* simple expression */
14 ReturnNode 12 - RETURN #13
Indexes used:
none
Traversals on graphs:
Id Depth Vertex collections Edge collections Filter conditions
6 1..1 persons knows
Optimization rules applied:
Id RuleName
1 move-calculations-up
2 remove-unnecessary-calculations它可以告诉我们以下几点:
你能做些什么来改善这种情况
您应该找到一种将复杂计算移出迭代的方法。虽然使用DATE_*函数可能很方便,但速度不快。应该计算要预先筛选的字符串年份:月份,然后在查询中对计算的字符串进行范围比较:
FILTER e.date > '2016:04:' && e.date < '2016:05:'Nate的执行情况:
for mo in 0..11
let month = date_subtract(concat(left(date_iso8601(date_now()),7),'-01T00:00:00.000Z'), mo, "month")
let nextMonth = date_subtract(concat(left(date_iso8601(date_now()),7),'-01T00:00:00.000Z'), mo-1, "month")
let monthNumber = date_month(month)
let msgCount = count(
for v, e in outbound "profileId" graph "MyGraph"
filter e.category == 'myCategory' && e.date > month && e.date < nextMonth
return 1
)
return {month: monthNumber, msgCount: msgCount}这大大加快了查询速度(快5倍)!
https://stackoverflow.com/questions/39155025
复制相似问题