Postgres table select 查询太慢

Postgres table select query is too slow

我有一个 gps 跟踪 application.It 有一个名为 gps_vehicle_data 的 table,其中经常存储传入的 gps 数据。我经常查询这个 table 来处理它,因为它只包含原始数据。最近,我目睹了在 table 上执行 select 语句的长时间延迟。下面是 EXPLAIN 的结果。我还尝试执行 VACUUM 并粘贴下面的结果。可能是什么原因?

EXPLAIN (ANALYZE, BUFFERS) select * from gps_vehicle_data;

                                                           QUERY PLAN                                                            
---------------------------------------------------------------------------------------------------------------------------------
 Seq Scan on gps_vehicle_data  (cost=0.00..130818.81 rows=1400881 width=1483) (actual time=209.129..62488.822 rows=9635 loops=1)
   Buffers: shared hit=13132 read=103678 dirtied=67 written=25
 Planning time: 0.050 ms
 Execution time: 62500.850 ms

真空输出。

VACUUM (VERBOSE,ANALYSE) gps_vehicle_data;
INFO:  vacuuming "public.gps_vehicle_data"
INFO:  index "gps_vehicle_data_pkey" now contains 1398939 row versions in 10509 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.07s/0.09u sec elapsed 9.38 sec.
INFO:  index "gps_vehicle_data_status_idx" now contains 1398939 row versions in 4311 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.03s/0.04u sec elapsed 4.50 sec.
INFO:  index "gps_vehicle_data_url_data_idx" now contains 1399004 row versions in 98928 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.76s/0.88u sec elapsed 82.74 sec.
INFO:  index "gps_vehicle_data_createdon_idx" now contains 1399007 row versions in 3946 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.00s/0.02u sec elapsed 1.92 sec.
INFO:  "gps_vehicle_data": found 0 removable, 1402484 nonremovable row versions in 116884 out of 116884 pages
DETAIL:  1401490 dead row versions cannot be removed yet.
There were 143431 unused item pointers.
Skipped 0 pages due to buffer pins.
0 pages are entirely empty.
CPU 1.70s/2.38u sec elapsed 200.61 sec.
INFO:  vacuuming "pg_toast.pg_toast_17296"
INFO:  index "pg_toast_17296_index" now contains 0 row versions in 1 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.00s/0.00u sec elapsed 0.01 sec.
INFO:  "pg_toast_17296": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
Skipped 0 pages due to buffer pins.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.01 sec.
INFO:  analyzing "public.gps_vehicle_data"
INFO:  "gps_vehicle_data": scanned 30000 of 116884 pages, containing 335 live rows and 359656 dead rows; 335 rows in sample, 1042851 estimated total rows
VACUUM

您阅读了超过 100000 个块以获得大约 10000 行,这意味着您的 table 几乎完全没有内容(它正在遭受 table 膨胀).

table 一定在某个时候包含了更多的数据,其中大部分已被删除,这导致了膨胀。

如@a_horse_with_no_name 所述,您的某些行无法回收,因为有一些旧事务阻止了它们,但是虽然 VACUUM 会释放死行,但不会重新组织 table 摆脱臃肿。

在这种情况下,正确的解决方案是使用 VACUUM (FULL, ANALYZE) gps_vehicle_dataANALYZE 只是为了很好的衡量,因为它看起来像您的 table 统计数据已关闭),这将重新组织table。但是请注意,当 VACUUM (FULL) 为 运行 时,对 table 的所有访问都被阻止。