I have a seven linestring tables that I buffered to create polygons of each line network. I then successively intersected each table (Figure 1 below).
I use the following sql query, but it take 36 min 56 sec for 373k rows. I used the method as shown @ https://postgis.net/documentation/tips/tip_intersection_faster/
DROP TABLE IF EXISTS public.pipe_vul_test;
CREATE TABLE pipe_vul_test AS
WITH int1 AS (
SELECT a.strm_dist, a.strm_order, a.slope,
b.hab_vul
, CASE
WHEN ST_CoveredBy(a.geom, b.geom)
THEN a.geom
ELSE
ST_Multi(
ST_Intersection(a.geom,b.geom)
) END As geom
FROM public.stream_dist_final AS a
INNER JOIN public.hab_vul_final b
ON (ST_Intersects(a.geom, b.geom)
AND Not ST_Touches(a.geom, b.geom) )
), int2 AS (
SELECT c.rd_dist, int1.strm_dist, int1.strm_order, int1.slope, int1.hab_vul
, CASE
WHEN ST_CoveredBy(int1.geom, c.geom)
THEN int1.geom
ELSE
ST_Multi(
ST_Intersection(int1.geom,c.geom)
) END As geom
FROM int1
INNER JOIN public.rd_dist_final AS c
ON (ST_Intersects(int1.geom,c.geom)
AND Not ST_Touches(int1.geom,c.geom) )
), int3 AS (
SELECT d.wet_dist, int2.rd_dist, int2.strm_dist, int2.strm_order, int2.slope, int2.hab_vul
, CASE
WHEN ST_CoveredBy(int2.geom, d.geom)
THEN int2.geom
ELSE
ST_Multi(
ST_Intersection(int2.geom, d.geom)
) END As geom
FROM int2
INNER JOIN public.wetland_dist_final AS d
ON (ST_Intersects(int2.geom, d.geom)
AND Not ST_Touches(int2.geom, d.geom) )
), int4 AS (
SELECT e.dwnrd_vul, int3.wet_dist, int3.rd_dist, int3.strm_dist, int3.strm_order, int3.slope, int3.hab_vul
, CASE
WHEN ST_CoveredBy(int3.geom, e.geom)
THEN int3.geom
ELSE
ST_Multi(
ST_Intersection(int3.geom, e.geom)
) END As geom
FROM int3
INNER JOIN rd_crossing.dwn_rd_cross AS e
ON (ST_Intersects(int3.geom, e.geom)
AND Not ST_Touches(int3.geom, e.geom) )
), int5 AS (
SELECT f.dwnwtr_vul, int4.dwnrd_vul, int4.wet_dist, int4.rd_dist, int4.strm_dist, int4.strm_order, int4.slope, int4.hab_vul
, CASE
WHEN ST_CoveredBy(int4.geom, f.geom)
THEN int4.geom
ELSE
ST_Multi(
ST_Intersection(int4.geom, f.geom)
) END As geom
FROM int4
INNER JOIN waterbody.dwn_wtr_cross AS f
ON (ST_Intersects(int4.geom, f.geom)
AND Not ST_Touches(int4.geom, f.geom) )
), int6 AS (
SELECT g.dwnpop_dist, int5.dwnwtr_vul, int5.dwnrd_vul, int5.wet_dist, int5.rd_dist, int5.strm_dist, int5.strm_order, int5.slope, int5.hab_vul
, CASE
WHEN ST_CoveredBy(int5.geom, g.geom)
THEN int5.geom
ELSE
ST_Multi(
ST_Intersection(int5.geom, g.geom)
) END As geom
FROM int5
INNER JOIN pop_centre.dwn_pop_cross AS g
ON (ST_Intersects(int5.geom, g.geom)
AND Not ST_Touches(int5.geom, g.geom) )
)
SELECT * FROM int6;
ALTER TABLE public.pipe_vul_test ADD COLUMN id SERIAL PRIMARY KEY; -- add id column
CREATE INDEX pipe_vul_test_geom_idx ON public.pipe_vul_test USING GIST (geom); -- create spatial index
Figure 1. Illustration of intersection outcome.
EXPLAIN report (all cte's at once): https://justpaste.it/7wkyj
EXPLAIN report (for each query separately) https://justpaste.it/bg8vi