使用ArangoDB已经有一段时间了,用它和Python一起开发是非常直接和快速的。
然而,我最近面临着一些问题与生产方面,这是一个裸机与这些规格:
- 英特尔至强E-2386 G 6c/12 t,3.50GHz
- 32 GB ECC 3200兆赫
- 2个512 GB NVME固态硬盘,采用RAID 1配置
ArangoDB版本包括:
当地:
- 费多拉36
- 阿拉伯数字b3 3.8.7
生产:
- Rocky Linux 9操作系统
- 阿拉伯数字b3 3.9.3
问题是非常简单的查询所需的时间很长,在本地环境中为毫秒级,而在生产环境中为整秒级。(搜索有41 k个文档,结果有350 k个文档)比本地(搜索有1 k个文档,结果有27 k个文档),但是我确实注意到生产中的一个缓慢的习惯,即使是较小的数字。
下面是生产概要查询:
Query String (415 chars, cacheable: false):
FOR entry in searches
FILTER entry.session_key == '21150583'
LET counters = (
FOR result in results_linkers
FILTER result.search_key == entry._key AND result.validation_automatic.status == 'completed'
COLLECT action = result.validation_automatic.action WITH COUNT INTO action_counter
RETURN { 'action': action, 'count': action_counter }
)
LIMIT 20
RETURN { 'search': entry, 'counters': counters }
Execution plan:
Id NodeType Calls Items Runtime [s] Comment
1 SingletonNode 1 1 0.00000 * ROOT
2 EnumerateCollectionNode 1 20 0.00737 - FOR entry IN searches /* full collection scan */ FILTER (entry.`session_key` == "21150583") /* early pruning */
14 LimitNode 1 20 0.00001 - LIMIT 0, 20
18 SubqueryStartNode 1 40 0.00001 - LET counters = ( /* subquery begin */
6 EnumerateCollectionNode 7136 7135580 3.33341 - FOR result IN results_linkers /* full collection scan, projections: `search_key`, `validation_automatic` */
7 CalculationNode 7136 7135580 1.36629 - LET #9 = ((result.`search_key` == entry.`_key`) && (result.`validation_automatic`.`status` == "completed")) /* simple expression */ /* collections used: result : results_linkers, entry : searches */
8 FilterNode 2 1854 0.12298 - FILTER #9
9 CalculationNode 2 1854 0.00024 - LET #11 = result.`validation_automatic`.`action` /* attribute expression */ /* collections used: result : results_linkers */
10 CollectNode 1 56 0.00013 - COLLECT action = #11 AGGREGATE action_counter = LENGTH() /* hash */
17 SortNode 1 56 0.00001 - SORT action ASC /* sorting strategy: standard */
11 CalculationNode 1 56 0.00002 - LET #13 = { "action" : action, "count" : action_counter } /* simple expression */
19 SubqueryEndNode 1 20 0.00001 - RETURN #13 ) /* subquery end */
15 CalculationNode 1 20 0.00001 - LET #15 = { "search" : entry, "counters" : counters } /* simple expression */ /* collections used: entry : searches */
16 ReturnNode 1 20 0.00000 - RETURN #15
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
5 move-calculations-down
6 reduce-extraction-to-projection
7 move-filters-into-enumerate
8 splice-subqueries
Query Statistics:
Writes Exec Writes Ign Scan Full Scan Index Filtered Peak Mem [b] Exec Time [s]
0 0 7176820 0 7174966 655360 4.83091
Query Profile:
Query Stage Duration [s]
initializing 0.00000
parsing 0.00004
optimizing ast 0.00001
loading collections 0.00000
instantiating plan 0.00003
optimizing plan 0.00031
executing 4.83051
finalizing 0.00002
这是当地的一个:
Query String (414 chars, cacheable: false):
FOR entry in searches
FILTER entry.session_key == '3307542'
LET counters = (
FOR result in results_linkers
FILTER result.search_key == entry._key AND result.validation_automatic.status == 'completed'
COLLECT action = result.validation_automatic.action WITH COUNT INTO action_counter
RETURN { 'action': action, 'count': action_counter }
)
LIMIT 20
RETURN { 'search': entry, 'counters': counters }
Execution plan:
Id NodeType Calls Items Runtime [s] Comment
1 SingletonNode 1 1 0.00001 * ROOT
2 EnumerateCollectionNode 1 1 0.00097 - FOR entry IN searches /* full collection scan */ FILTER (entry.`session_key` == "3307542") /* early pruning */
14 LimitNode 1 1 0.00001 - LIMIT 0, 20
18 SubqueryStartNode 1 2 0.00001 - LET counters = ( /* subquery begin */
6 EnumerateCollectionNode 28 27775 0.02148 - FOR result IN results_linkers /* full collection scan, projections: `search_key`, `validation_automatic` */
7 CalculationNode 28 27775 0.00866 - LET #9 = ((result.`search_key` == entry.`_key`) && (result.`validation_automatic`.`status` == "completed")) /* simple expression */ /* collections used: result : results_linkers, entry : searches */
8 FilterNode 1 97 0.00169 - FILTER #9
9 CalculationNode 1 97 0.00002 - LET #11 = result.`validation_automatic`.`action` /* attribute expression */ /* collections used: result : results_linkers */
10 CollectNode 1 3 0.00002 - COLLECT action = #11 AGGREGATE action_counter = LENGTH() /* hash */
17 SortNode 1 3 0.00001 - SORT action ASC /* sorting strategy: standard */
11 CalculationNode 1 3 0.00001 - LET #13 = { "action" : action, "count" : action_counter } /* simple expression */
19 SubqueryEndNode 1 1 0.00001 - RETURN #13 ) /* subquery end */
15 CalculationNode 1 1 0.00001 - LET #15 = { "search" : entry, "counters" : counters } /* simple expression */ /* collections used: entry : searches */
16 ReturnNode 1 1 0.00001 - RETURN #15
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
5 move-calculations-down
6 reduce-extraction-to-projection
7 move-filters-into-enumerate
8 splice-subqueries
Query Statistics:
Writes Exec Writes Ign Scan Full Scan Index Filtered Peak Mem [b] Exec Time [s]
0 0 28901 0 28804 360448 0.03434
Query Profile:
Query Stage Duration [s]
initializing 0.00002
parsing 0.00012
optimizing ast 0.00002
loading collections 0.00001
instantiating plan 0.00007
optimizing plan 0.00117
executing 0.03293
finalizing 0.00003
另一个需要补充的细节是,我使用的数据库有“单个”大集合,检索数据时查找键,就像老式的关系数据库一样。这也是一种错误的方法吗?集合会随着时间的推移而增长,所以我对此有点担心。
谢谢你在这件事上帮我的人!
2条答案
按热度按时间afdcj2ne1#
我建议您考虑为您的收藏添加索引。
我要添加的第一个索引是'searches'集合上的Persistent索引,特别是键'session_key'上的索引。
第二个我要添加的索引是'results_linkers'集合上的一个Persistent索引,特别是键'validation_automatic. status'上的索引。使用这个索引,也可以测试将第二个键添加到键'result.validation_automatic. action'的索引中,这可能会对collect命令有所帮助。
添加索引后,执行相同的查询分析,并确认在"使用的索引“部分中选择了您的索引。如果您的索引没有在此处列出,则它们没有任何优势,您需要更改索引所基于的键,以查看它们是否触发。
添加索引后,您不需要重新启动服务器。当下一个AQL查询命中服务器时,它将确定是否有任何索引有帮助。
根据我的经验,索引可以将查询性能提高10倍到1000倍,具体取决于您的查询。
看看有没有帮助。
当使用小数据集进行本地开发时,很容易认为您的查询执行得很好,但在生产中却发现它们运行得很慢。
解决这个问题的最佳方法是有一个“PVT -生产验证测试”空间,在那里您可以在恢复生产数据的数据库上测试您的新代码,如果您能够做到这一点。
看看这些索引是否有帮助,如果没有帮助,则调整它们,如果没有帮助,则忽略索引。
i1icjdpr2#
您的互联网速度慢吗?我会尝试使用traceroute来确定您的互联网是否是查询速度慢的原因。通常,本地查询速度和生产查询速度之间的差异与资源使用或互联网速度有关。这是我的经验。您也可以在查询运行时使用top命令检查资源使用情况。
这两个问题对于确定瓶颈是与网络还是资源有关很有帮助。如果这两个问题都没有真正显示瓶颈,那么可能是配置问题。除非您的本地开发环境和生产环境的配置完全相同。
让我知道你用这些发现了什么。