PostgreSQL在9.6引入了并行查詢功能,非常有用,若查詢以并行方式執(zhí)行息罗,速率可以有幾倍的提升。平時(shí)與地理數(shù)據(jù)打交道較多才沧,所以對(duì)地理數(shù)據(jù)的操作是否可以并行執(zhí)行較為感興趣迈喉,這里我們就來(lái)看看究竟,研究一下涉及postgis的查詢是否可以以并行執(zhí)行温圆。
查詢并行方式執(zhí)行需要怎樣的條件
如果想讓PostgreSQL將查詢以并行方式執(zhí)行挨摸,那么以下兩個(gè)條件必須滿足:
- max_parallel_workers_per_gather,每個(gè)Gather 節(jié)點(diǎn)可調(diào)用的worker數(shù)量岁歉,該值需要設(shè)置大于0的整數(shù)得运,否則Gather節(jié)點(diǎn)沒(méi)有可用的worker,自然所有事情要自己做刨裆,自己化身為worker澈圈,也就沒(méi)有了并行。
- dynamic-shared-memory-type帆啃,控制各個(gè)并行進(jìn)程間通信存儲(chǔ)數(shù)據(jù)的內(nèi)存瞬女,必須設(shè)置,不能為none努潘,否則進(jìn)程間不能通信诽偷,何來(lái)并行協(xié)作坤学。
此外,查詢需要滿足其它條件报慕,才有可能以并行方式執(zhí)行:
- 查詢中不能包含寫(xiě)數(shù)據(jù)操作或可能存在鎖定記錄的操作深浮;
- 查詢中不能包含
PARALLEL UNSAFE
的函數(shù); - 被并行執(zhí)行的查詢中的子查詢不會(huì)以并行方式執(zhí)行眠冈;
- 事務(wù)隔離級(jí)別不能是
serializable
飞苇。
其它需要設(shè)置可能會(huì)影響到并行執(zhí)行效率的參數(shù):
- max_worker_processes,后臺(tái)進(jìn)程的最大數(shù)量蜗顽,默認(rèn)值是8布卡;
- max_parallel_workers, 可用于并行查詢的最大進(jìn)程數(shù)雇盖,這個(gè)值肯定超不過(guò)
max_worker_processes
忿等,因?yàn)椴⑿械膚orker也是取用max_worker_processes
初始化的worker; - max_parallel_maintenance_workers崔挖,工具命令運(yùn)行的最大并行進(jìn)程贸街,當(dāng)前只有
CREATE INDEX
支持,且只有B-tree支持狸相。
如何查看特定查詢是否可以并行執(zhí)行
可以通過(guò)EXPLAIN
查看執(zhí)行計(jì)劃來(lái)確定查詢是否是并行薛匪,是否走索引。
Gather or Gather Merge node
地理數(shù)據(jù)是否可以并行執(zhí)行
- 確認(rèn)已創(chuàng)建索引
首先我們確認(rèn)表的空間字段是有建立過(guò)空間索引的脓鹃,數(shù)據(jù)是OSM的數(shù)據(jù):
SELECT * FROM pg_indexes WHERE tablename = 'planet_osm_polygon';
得到如下結(jié)果:
public planet_osm_polygon planet_osm_polygon_index CREATE INDEX planet_osm_polygon_index ON public.planet_osm_polygon USING gist (way) WITH (fillfactor='100')
public planet_osm_polygon planet_osm_polygon_gist_idx CREATE INDEX planet_osm_polygon_gist_idx ON public.planet_osm_polygon USING gist (way)
public planet_osm_polygon planet_osm_polygon_btree_idx CREATE INDEX planet_osm_polygon_btree_idx ON public.planet_osm_polygon USING btree (name)
public planet_osm_polygon planet_osm_polygon_admin_level_btree_idx CREATE INDEX planet_osm_polygon_admin_level_btree_idx ON public.planet_osm_polygon USING btree (admin_level)
public planet_osm_polygon planet_osm_polygon_admin_way_area_idx CREATE INDEX planet_osm_polygon_admin_way_area_idx ON public.planet_osm_polygon USING btree (way_area)