最近一次查询大约需要9分钟才能完成。为了确定原因,我使用了EXPLAIN ANALYZE
来解决问题。从输出看,似乎所有内容都具有适当的索引,这只需要花费很长时间。
我将查询和结果放在下面。是否由于数据量而花费这么长时间?还是我做错了什么。我的查询是否需要从根本上进行更改以提高性能?
其他信息:PostgreSQL 10.6。 Xeon @ 3.4Ghz上的系统,具有SSD和24GB内存,因此它是相当不错的台式机规格。
SELECT s.start_date, s.end_date, s.resources, s.activity_index, r.resource_id, sa.usedresourceset
FROM rm_o_resource_usage_instance_splits_new s
INNER JOIN rm_o_resource_usage r ON s.usage_id = r.id
INNER JOIN scheduledactivities sa ON s.activity_index = sa.activity_index
AND r.schedule_id = sa.solution_id
and s.solution = sa.solution_id
WHERE r.schedule_id = 14349
ORDER BY r.resource_id, s.start_date
----------------------------------------------------------------
"Sort (cost=18.01..18.01 rows=1 width=86) (actual time=541075.198..541099.504 rows=65354 loops=1)"
" Sort Key: r.resource_id, s.start_date"
" Sort Method: external merge Disk: 8016kB"
" -> Nested Loop (cost=0.85..18.00 rows=1 width=86) (actual time=6.946..540671.934 rows=65354 loops=1)"
" Join Filter: (s.activity_index = sa.activity_index)"
" Rows Removed by Join Filter: 3550029280"
" -> Nested Loop (cost=0.42..12.93 rows=1 width=98) (actual time=0.074..1795.054 rows=65354 loops=1)"
" Join Filter: (s.usage_id = r.id)"
" Rows Removed by Join Filter: 248018"
" -> Index Scan using rm_o_resource_usage_instance_splits_new_solution_idx on rm_o_resource_usage_instance_splits_new s (cost=0.42..4.76 rows=1 width=69) (actual time=0.032..36.395 rows=65354 loops=1)"
" Index Cond: (solution = 14349)"
" -> Seq Scan on rm_o_resource_usage r (cost=0.00..8.15 rows=2 width=45) (actual time=0.018..0.019 rows=5 loops=65354)"
" Filter: (schedule_id = 14349)"
" Rows Removed by Filter: 332"
" -> Index Scan using scheduled_activities_idx on scheduledactivities sa (cost=0.42..5.06 rows=1 width=16) (actual time=0.007..4.937 rows=54321 loops=65354)"
" Index Cond: (solution_id = 14349)"
"Planning time: 1.547 ms"
"Execution time: 541104.491 ms"
答案 0 :(得分:2)
查看您的查询执行计划会花费大量时间进行排序
"Sort (cost=18.01..18.01 rows=1 width=86) (actual time=541075.198..541099.504 rows=65354 loops=1)"
" Sort Key: r.resource_id, s.start_date"
" Sort Method: external merge Disk: 8016kB"
我建议您按照work_mem所述为PostgreSQL
增加here 参数
如果您执行许多复杂的排序并且有很多内存,那么增加work_mem参数可以使PostgreSQL做更大的事情 毫无疑问,内存中的排序将比基于磁盘的排序更快 等价物。
此大小适用于每个用户完成的每种排序,并且 复杂的查询可以使用多个工作内存排序缓冲区。设置它 到50MB,并有30个用户提交查询,您很快就会使用 1.5GB的实际内存。此外,如果查询涉及对8个表进行合并排序,则需要8倍work_mem。你需要 考虑设置max_connections的大小 参数正确。这是数据仓库系统的设置, 用户提交非常大的查询时,可以随时使用 许多GB的内存。
log_temp_files可用于记录排序,哈希和临时文件, 在确定是否将各种数据溢出到磁盘而不是磁盘上时很有用 适合内存。您可以使用EXPLAIN看到排序溢出到磁盘 以及分析计划。例如,如果您看到类似“排序”的行 方法:外部合并磁盘:EXPLAIN ANALYZE的输出中的7526kB, 至少8MB的work_mem会将中间数据保留在内存中 并可能会缩短查询响应时间(尽管可能会花费一些时间 超过8MB的空间完全作为数据存储在内存中 在磁盘上以更紧凑的格式存储。)