Postgresql
非常簡單的只讀 SELECT 不在 postrgresql 中並行執行
我正在嘗試在一個大表上做一個簡單的 SELECT,但它沒有並行執行:
my_db=> explain (analyze, buffers) select value from my_table; Seq Scan on my_table (cost=0.00..94433357.34 rows=5441810434 width=4) (actual time=0.029..1519364.787 rows=4897721407 loops=1) Buffers: shared hit=1126394 read=38888859 dirtied=1926396 written=284 Planning time: 2.277 ms Execution time: 2468388.489 ms
如果我執行 max() 操作,它會並行執行:
my_db=> explain (analyze, buffers) select max(value) from my_table; Finalize Aggregate (cost=48552456.41..48552456.42 rows=1 width=4) (actual time=1347796.993..1347796.993 rows=1 loops=1) Buffers: shared hit=1173785 read=38870105 dirtied=30813 -> Gather (cost=48552455.58..48552456.39 rows=8 width=4) (actual time=1347796.953..1347796.969 rows=9 loops=1) Workers Planned: 8 Workers Launched: 8 Buffers: shared hit=1173785 read=38870105 dirtied=30813 -> Partial Aggregate (cost=48551455.58..48551455.59 rows=1 width=4) (actual time=1347790.862..1347790.862 rows=1 loops=9) Buffers: shared hit=1172674 read=38870104 dirtied=30813 -> Parallel Seq Scan on my_table (cost=0.00..46849720.06 rows=680694206 width=4) (actual time=0.213..1048428.195 rows=544206420 loops=9) Buffers: shared hit=1172674 read=38870104 dirtied=30813 Planning time: 0.761 ms Execution time: 1347985.127 ms
為什麼 SELECT 不是並行完成的?
該表有數十億行。DBA 做了一些索引——我不知道這到底是什麼意思,但我讀到索引掃描在 PostgreSQL 9.6.8 中不是並行的,但它無論如何都在進行順序掃描。
我在 x86_64-pc-linux-gnu 上使用 PostgreSQL 9.6.8,由 gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9) 編譯,64 位
該表具有以下結構:
my_db=> \d my_table id | bigint | not null default nextval('my_table_id_seq'::regclass) datetime | timestamp(0) without time zone | not null value | real | not null my_id | smallint | not null my_flag | boolean | not null my_db=> \d my_table_id_seq sequence_name | name | my_table_id_seq last_value | bigint | 4971842011 start_value | bigint | 1 increment_by | bigint | 1 max_value | bigint | 9223372036854775807 min_value | bigint | 1 cache_value | bigint | 1 log_cnt | bigint | 22 is_cycled | boolean | f is_called | boolean | t
並行 SELECT MAX(value) 仍然需要相當長的時間:
my_db=> \timing on Timing is on. my_db=> select max(value) from my_table; 9333 Time: 1342377.208 ms
查詢領導者是唯一與前端通信的程序。查詢的非聚合版本的所有 SELECT 數據都必須從並行工作人員編組到查詢領導者。這很昂貴,因此在這裡使用並行查詢幾乎肯定會適得其反。無論如何,您都可以通過將 parallel_tuple_cost 和 parallel_setup_cost 設置為零來獲得一個。
在進行 count(*) 聚合時,每個並行工作人員只需向領導者發送一條資訊,即部分計數。這顯然更有價值。