From bf66be079b4d72477ccd4b9058eb139b89a45cff Mon Sep 17 00:00:00 2001 From: bruhnild Date: Tue, 16 Jan 2024 10:21:38 +0100 Subject: [PATCH] improve spatial intersection for sql views refs : https://github.com/GeotrekCE/Geotrek-admin/pull/3601 (contributed by @amandine-sahl) --- docs/changelog.rst | 3 +- .../core/templates/core/sql/post_60_views.sql | 36 ++++------ .../templates/feedback/sql/post_10_views.sql | 22 +++--- .../infrastructure/sql/post_10_views.sql | 42 ++++------- .../maintenance/sql/post_20_views.sql | 24 +++---- .../templates/outdoor/sql/post_20_views.sql | 26 ++++--- .../sensitivity/sql/post_10_views.sql | 24 +++---- .../templates/signage/sql/post_10_views.sql | 42 ++++------- .../templates/tourism/sql/post_20_views.sql | 48 ++++++------- .../templates/trekking/sql/post_30_views.sql | 72 +++++++------------ 10 files changed, 136 insertions(+), 203 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index c09c82784a..eeb34ff58a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,7 +10,7 @@ CHANGELOG **New features** --Land: Add ``CirculationEdge`` model to manage circulation types and authorization types in the land module (#3578) +- Land: Add ``CirculationEdge`` model to manage circulation types and authorization types in the land module (#3578) - Generalize``AccessMean`` model and add field ``access`` to ``Intervention`` (#3819) **Improvements** @@ -20,6 +20,7 @@ CHANGELOG - Allow to set headers in requests from Parsers (#3861) - Sort bladeType alphabetically (#3821) - Update ``Intervention`` model to have begin & end date (#3825) +- Improve performance in spatial intersection (zoning district and zoning city) for sql views (#3600) **Documentation** diff --git a/geotrek/core/templates/core/sql/post_60_views.sql b/geotrek/core/templates/core/sql/post_60_views.sql index 849c47d905..00af59b0b8 100644 --- a/geotrek/core/templates/core/sql/post_60_views.sql +++ b/geotrek/core/templates/core/sql/post_60_views.sql @@ -30,28 +30,16 @@ SELECT a.id, a.geom FROM v_trails a LEFT JOIN authent_structure d ON a.structure_id = d.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM - (SELECT core_topology.geom, - core_topology.id - FROM core_trail, - core_topology - WHERE core_trail.topo_object_id = core_topology.id - AND core_topology.deleted = FALSE) a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM - (SELECT core_topology.geom, - core_topology.id - FROM core_trail, - core_topology - WHERE core_trail.topo_object_id = core_topology.id - AND core_topology.deleted = FALSE) a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) g ON a.id = g.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) f ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) g ON true ; diff --git a/geotrek/feedback/templates/feedback/sql/post_10_views.sql b/geotrek/feedback/templates/feedback/sql/post_10_views.sql index 47dd8ff111..30adc560c2 100644 --- a/geotrek/feedback/templates/feedback/sql/post_10_views.sql +++ b/geotrek/feedback/templates/feedback/sql/post_10_views.sql @@ -23,15 +23,17 @@ LEFT JOIN public.feedback_reportactivity b ON a.activity_id = b.id LEFT JOIN public.feedback_reportcategory c ON a.category_id = c.id LEFT JOIN public.feedback_reportstatus d ON a.status_id = d.id LEFT JOIN public.feedback_reportproblemmagnitude e ON a.problem_magnitude_id = e.id -LEFT JOIN (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM feedback_report a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM feedback_report a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) g ON a.id = g.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) f ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) g ON true WHERE deleted IS FALSE ; diff --git a/geotrek/infrastructure/templates/infrastructure/sql/post_10_views.sql b/geotrek/infrastructure/templates/infrastructure/sql/post_10_views.sql index cad5ed34c8..96bf63c32a 100644 --- a/geotrek/infrastructure/templates/infrastructure/sql/post_10_views.sql +++ b/geotrek/infrastructure/templates/infrastructure/sql/post_10_views.sql @@ -75,33 +75,17 @@ LEFT JOIN infrastructure_infrastructurecondition c ON a.condition_id = c.id LEFT JOIN infrastructure_infrastructureusagedifficultylevel d ON a.usage_difficulty_id = d.id LEFT JOIN infrastructure_infrastructuremaintenancedifficultylevel e ON a.maintenance_difficulty_id = e.id LEFT JOIN common_accessmean j ON a.access_id = j.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM - (SELECT e.geom, - e.id - FROM infrastructure_infrastructure t, - infrastructure_infrastructuretype b, - core_topology e - WHERE t.topo_object_id = e.id - AND t.type_id = b.id - AND e.deleted = FALSE) a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM - (SELECT e.geom, - e.id - FROM infrastructure_infrastructure t, - infrastructure_infrastructuretype b, - core_topology e - WHERE t.topo_object_id = e.id - AND t.type_id = b.id - AND e.deleted = FALSE) a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) g ON a.id = g.id -LEFT JOIN authent_structure i ON a.structure_id = i.id +LEFT JOIN LATERAL + ( SELECT array_to_string(array_agg(b_1.name + ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id ) f ON TRUE +LEFT JOIN LATERAL + ( SELECT array_to_string(array_agg(b_1.name + ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id ) g ON TRUE +LEFT JOIN authent_structure i ON a.structure_id = i.id ; diff --git a/geotrek/maintenance/templates/maintenance/sql/post_20_views.sql b/geotrek/maintenance/templates/maintenance/sql/post_20_views.sql index c828a76f48..82fe311bdf 100644 --- a/geotrek/maintenance/templates/maintenance/sql/post_20_views.sql +++ b/geotrek/maintenance/templates/maintenance/sql/post_20_views.sql @@ -44,18 +44,18 @@ LEFT JOIN core_stake d ON a.stake_id = d.id LEFT JOIN authent_structure e ON a.structure_id = e.id LEFT JOIN maintenance_project h ON a.project_id = h.id LEFT JOIN common_accessmean accessmean ON a.access_id = accessmean.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM maintenance_intervention a - JOIN zoning_city b ON ST_INTERSECTS (st_pointonsurface(a.geom_3d), b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM maintenance_intervention a - JOIN zoning_district b ON ST_INTERSECTS (st_pointonsurface(a.geom_3d), b.geom) - GROUP BY a.id) g ON a.id = g.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom_3d, b_1.geom) + GROUP BY a.id + ) f ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom_3d, b_1.geom) + GROUP BY a.id + ) g ON true LEFT JOIN (SELECT array_to_string(ARRAY_AGG (disorder ORDER BY a.id), ', ', '_') disorder, c.id diff --git a/geotrek/outdoor/templates/outdoor/sql/post_20_views.sql b/geotrek/outdoor/templates/outdoor/sql/post_20_views.sql index d74b89c0ff..8eb1c31a5f 100644 --- a/geotrek/outdoor/templates/outdoor/sql/post_20_views.sql +++ b/geotrek/outdoor/templates/outdoor/sql/post_20_views.sql @@ -215,20 +215,18 @@ SELECT a.id, FROM public.outdoor_site a JOIN outdoor_site_geom sg ON a.id = sg.id AND NOT ST_IsEmpty(sg.geom) LEFT JOIN authent_structure b ON a.structure_id = b.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM - outdoor_site a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) c ON a.id = c.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM - outdoor_site a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) d ON a.id = d.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) c ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) d ON true LEFT JOIN outdoor_sitetype e ON a.type_id = e.id LEFT JOIN outdoor_practice f ON a.practice_id = f.id LEFT JOIN diff --git a/geotrek/sensitivity/templates/sensitivity/sql/post_10_views.sql b/geotrek/sensitivity/templates/sensitivity/sql/post_10_views.sql index d2421e6eaa..1c7fa352b2 100644 --- a/geotrek/sensitivity/templates/sensitivity/sql/post_10_views.sql +++ b/geotrek/sensitivity/templates/sensitivity/sql/post_10_views.sql @@ -99,18 +99,18 @@ LEFT JOIN ( ) r ON r.sensitivearea_id = a.id LEFT JOIN sensitivity_species h ON a.species_id = h.id LEFT JOIN authent_structure d ON a.structure_id = d.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM sensitivity_sensitivearea a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM sensitivity_sensitivearea a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) g ON a.id = g.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) f ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) g ON true WHERE deleted IS FALSE ; diff --git a/geotrek/signage/templates/signage/sql/post_10_views.sql b/geotrek/signage/templates/signage/sql/post_10_views.sql index c625e8fa3b..691df95d7e 100644 --- a/geotrek/signage/templates/signage/sql/post_10_views.sql +++ b/geotrek/signage/templates/signage/sql/post_10_views.sql @@ -86,37 +86,21 @@ LEFT JOIN ( WITH signage_condition AS ( LEFT JOIN signage_sealing d ON a.sealing_id = d.id LEFT JOIN authent_structure e ON a.structure_id = e.id LEFT JOIN common_accessmean i ON a.access_id = i.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM - (SELECT e.id, - e.geom - FROM signage_signage t, - signage_signagetype b, - core_topology e - WHERE t.topo_object_id = e.id - AND t.type_id = b.id - AND e.deleted = FALSE ) a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM - (SELECT e.id, - e.geom - FROM signage_signage t, - signage_signagetype b, - core_topology e - WHERE t.topo_object_id = e.id - AND t.type_id = b.id - AND e.deleted = FALSE ) a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) g ON a.id = g.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) f ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) g ON true LEFT JOIN (SELECT organism, b.topo_object_id FROM common_organism a - JOIN signage_signage b ON a.id = b.manager_id) h ON a.topo_object_id = h.topo_object_id + JOIN signage_signage b ON a.id = b.manager_id) h ON a.topo_object_id = h.topo_object_id ; diff --git a/geotrek/tourism/templates/tourism/sql/post_20_views.sql b/geotrek/tourism/templates/tourism/sql/post_20_views.sql index 79ccd2a710..2718db6fb1 100644 --- a/geotrek/tourism/templates/tourism/sql/post_20_views.sql +++ b/geotrek/tourism/templates/tourism/sql/post_20_views.sql @@ -137,18 +137,18 @@ LEFT JOIN GROUP BY c.id) p ON a.id = p.id LEFT JOIN authent_structure c ON a.structure_id = c.id LEFT JOIN common_reservationsystem d ON a.reservation_system_id = d.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM tourism_touristiccontent a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM tourism_touristiccontent a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) g ON a.id = g.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) f ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) g ON true WHERE deleted IS FALSE ; @@ -221,18 +221,18 @@ LEFT JOIN public.authent_structure c ON a.structure_id = c.id LEFT JOIN public.tourism_touristiceventorganizer d ON a.organizer_id = d.id LEFT JOIN public.tourism_cancellationreason cr ON a.cancellation_reason_id = cr.id LEFT JOIN public.tourism_touristiceventplace p ON a.place_id = p.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM tourism_touristicevent a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM tourism_touristicevent a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) g ON a.id = g.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) f ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) g ON true LEFT JOIN (SELECT c.id, array_to_string(ARRAY_AGG (a.label ORDER BY a.id), ', ', '_') labels diff --git a/geotrek/trekking/templates/trekking/sql/post_30_views.sql b/geotrek/trekking/templates/trekking/sql/post_30_views.sql index fd8eb0dc7e..044c0364ac 100644 --- a/geotrek/trekking/templates/trekking/sql/post_30_views.sql +++ b/geotrek/trekking/templates/trekking/sql/post_30_views.sql @@ -259,30 +259,18 @@ SELECT a.id, FROM v_poi a LEFT JOIN trekking_poitype b ON a.type_id = b.id LEFT JOIN authent_structure c ON a.structure_id = c.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM - (SELECT e.geom, - e.id - FROM trekking_poi i, - core_topology e - WHERE i.topo_object_id = e.id - AND e.deleted = FALSE) a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM - (SELECT e.geom, - e.id - FROM trekking_poi i, - core_topology e - WHERE i.topo_object_id = e.id - AND e.deleted = FALSE) a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) g ON a.id = g.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) f ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) g ON true ; --Services @@ -318,28 +306,16 @@ SELECT a.id, FROM v_services a LEFT JOIN trekking_servicetype b ON a.type_id = b.id LEFT JOIN authent_structure c ON a.structure_id = c.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_city, - a.id - FROM - (SELECT e.geom, - e.id - FROM trekking_service i, - core_topology e - WHERE i.topo_object_id = e.id - AND e.deleted = FALSE) a - JOIN zoning_city b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) f ON a.id = f.id -LEFT JOIN - (SELECT array_to_string(ARRAY_AGG (b.name ORDER BY b.name), ', ', '_') zoning_district, - a.id - FROM - (SELECT e.geom, - e.id - FROM trekking_service i, - core_topology e - WHERE i.topo_object_id = e.id - AND e.deleted = FALSE) a - JOIN zoning_district b ON ST_INTERSECTS (a.geom, b.geom) - GROUP BY a.id) g ON a.id = g.id +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_city + FROM zoning_city b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) f ON true +LEFT JOIN LATERAL ( + SELECT array_to_string(array_agg(b_1.name ORDER BY b_1.name), ', '::text, '_'::text) AS zoning_district + FROM zoning_district b_1 + WHERE st_intersects(a.geom, b_1.geom) + GROUP BY a.id + ) g ON true ; \ No newline at end of file