使用3个FOR循环优化SQL查询
我有一个完整的SQL查询。但是,它非常非常慢。我正在寻找一种方法来优化它使用3个FOR循环优化SQL查询,sql,postgresql,query-optimization,postgis,Sql,Postgresql,Query Optimization,Postgis,我有一个完整的SQL查询。但是,它非常非常慢。我正在寻找一种方法来优化它 CREATE TABLE trajectory_geom ( id SERIAL PRIMARY KEY, trajectory_id BIGINT, user_id BIGINT, geom GEOMETRY(Linestring, 4326) ); INSERT INTO
CREATE TABLE trajectory_geom (
id SERIAL PRIMARY KEY,
trajectory_id BIGINT,
user_id BIGINT,
geom GEOMETRY(Linestring, 4326)
);
INSERT INTO trajectory_geom (trajectory_id, user_id, geom)
SELECT
p.trajectory_id,
p.user_id,
ST_Transform(ST_MakeLine(p.geom), 4326)
FROM point p
GROUP BY p.trajectory_id
;
DO $$
DECLARE
urow record;
vrow record;
wrow record;
BEGIN
FOR wrow IN
SELECT DISTINCT(p.user_id) FROM point p
LOOP
raise notice 'User id: %', wrow.user_id;
FOR vrow IN
SELECT DISTINCT(p.trajectory_id) FROM point p WHERE p.user_id = wrow.user_id
LOOP
FOR urow IN
SELECT
analyzed_tr.*
FROM trajectory_start_end_geom analyzed_tr
WHERE
analyzed_tr.user_id = wrow.user_id
AND
ST_Intersects (
(
analyzed_tr.start_geom
)
,
(
SELECT g.geom
FROM trajectory_geom g
WHERE g.trajectory_id = vrow.trajectory_id
)
) = TRUE
LOOP
INSERT INTO trajectories_intercepting_with_starting_point (initial_trajectory_id, mathced_trajectory_id, user_id)
SELECT
vrow.trajectory_id,
urow.trajectory_id,
wrow.user_id
WHERE urow.trajectory_id <> vrow.trajectory_id
;
END LOOP;
END LOOP;
END LOOP;
END;
$$;
这应该可以做到:
WITH vrow AS(
INSERT INTO trajectory_geom (trajectory_id, user_id, geom)
SELECT
p.trajectory_id,
p.user_id,
ST_Transform(ST_MakeLine(p.geom), 4326) AS geom
FROM point p
GROUP BY p.trajectory_id
RETURNING trajectory_id, user_id, geom
)
INSERT INTO trajectories_intercepting_with_starting_point (initial_trajectory_id, mathced_trajectory_id, user_id)
SELECT
vrow.trajectory_id,
urow.trajectory_id,
vrow.user_id
FROM trajectory_start_end_geom AS urow
JOIN vrow
ON urow.user_id = vrow.user_id
AND urow.trajectory_id <> vrow.trajectory_id
AND ST_Intersects(urow.start_geom, vrow.geom)
,其中vrow为(
插入轨迹\几何(轨迹\ id、用户\ id、几何)
挑选
p、 我的身份证,
p、 用户id,
ST_变换(ST_生成线(p.geom),4326)作为geom
从p点开始
按p.U.id分组
返回轨迹id、用户id、几何
)
插入带有起始点的轨迹截取(初始轨迹id、数学轨迹id、用户id)
挑选
vrow.u\id,
欧洲联盟,
vrow.user\u id
从轨道开始到结束
加入vrow
在urow.user\u id=vrow.user\u id上
和urow.tracture\u id vrow.tracture\u id
与圣母院相交(urow.start\u geom,vrow.geom)
如果您不需要插入
轨迹_geom
消除它(CTE)将加速它这应该可以做到:
WITH vrow AS(
INSERT INTO trajectory_geom (trajectory_id, user_id, geom)
SELECT
p.trajectory_id,
p.user_id,
ST_Transform(ST_MakeLine(p.geom), 4326) AS geom
FROM point p
GROUP BY p.trajectory_id
RETURNING trajectory_id, user_id, geom
)
INSERT INTO trajectories_intercepting_with_starting_point (initial_trajectory_id, mathced_trajectory_id, user_id)
SELECT
vrow.trajectory_id,
urow.trajectory_id,
vrow.user_id
FROM trajectory_start_end_geom AS urow
JOIN vrow
ON urow.user_id = vrow.user_id
AND urow.trajectory_id <> vrow.trajectory_id
AND ST_Intersects(urow.start_geom, vrow.geom)
,其中vrow为(
插入轨迹\几何(轨迹\ id、用户\ id、几何)
挑选
p、 我的身份证,
p、 用户id,
ST_变换(ST_生成线(p.geom),4326)作为geom
从p点开始
按p.U.id分组
返回轨迹id、用户id、几何
)
插入带有起始点的轨迹截取(初始轨迹id、数学轨迹id、用户id)
挑选
vrow.u\id,
欧洲联盟,
vrow.user\u id
从轨道开始到结束
加入vrow
在urow.user\u id=vrow.user\u id上
和urow.tracture\u id vrow.tracture\u id
与圣母院相交(urow.start\u geom,vrow.geom)
如果您不需要插入到
轨迹_geom
中,则消除它(以及CTE)将加快它的速度尝试此SQL查询。希望这有帮助
INSERT INTO trajectories_intercepting_with_starting_point
(initial_trajectory_id, mathced_trajectory_id, user_id)
SELECT
TG.trajectory_id AS first_trajectory_id,
TG2.trajectory_id AS last_trajectory_id,
TG.user_id
FROM Trajectory_geom AS TG
JOIN Trajectory_geom AS TG2 ON TG.user_id = TG2.user_id
AND TG.trajectory_id < TG2.trajectory_id
JOIN Trajectory_start_end_geom AS TSE ON TSE.trajectory_id = TG.trajectory_id
WHERE ST_Intersects(TSE.start_geom, TG2.geom) = TRUE
插入到轨迹中\u拦截\u和\u起点\u
(初始轨迹id、数学轨迹id、用户id)
挑选
TG.轨迹id作为第一个轨迹id,
TG2.tracks_id作为最后一个_tracks_id,
TG.user\u id
从轨迹_geom到TG
将轨迹_geom作为TG2连接到TG.user_id=TG2.user_id
和TG.tracept_id
尝试此SQL查询。希望这有帮助
INSERT INTO trajectories_intercepting_with_starting_point
(initial_trajectory_id, mathced_trajectory_id, user_id)
SELECT
TG.trajectory_id AS first_trajectory_id,
TG2.trajectory_id AS last_trajectory_id,
TG.user_id
FROM Trajectory_geom AS TG
JOIN Trajectory_geom AS TG2 ON TG.user_id = TG2.user_id
AND TG.trajectory_id < TG2.trajectory_id
JOIN Trajectory_start_end_geom AS TSE ON TSE.trajectory_id = TG.trajectory_id
WHERE ST_Intersects(TSE.start_geom, TG2.geom) = TRUE
插入到轨迹中\u拦截\u和\u起点\u
(初始轨迹id、数学轨迹id、用户id)
挑选
TG.轨迹id作为第一个轨迹id,
TG2.tracks_id作为最后一个_tracks_id,
TG.user\u id
从轨迹_geom到TG
将轨迹_geom作为TG2连接到TG.user_id=TG2.user_id
和TG.tracept_id
为什么不在一个查询中而不是在一个过程中执行呢?实际上我想要一个查询。只是过程是我设法想出的你不需要任何循环,你可以通过连接你需要的表来实现这一点。你能添加到你的问题简单的数据库模式吗?我认为使用联接运算符可以很容易地解决此任务。为什么不在单个查询中而不是在过程中执行此任务?实际上,我需要单个查询。只是过程是我设法想出的你不需要任何循环,你可以通过连接你需要的表来实现这一点。你能添加到你的问题简单的数据库模式吗?我认为使用JOIN运算符可以很容易地解决此任务。我不熟悉返回语法并遇到错误:错误:表“p”第9行的子句条目中缺少:返回p.tracture\u id、p.user\u id、geom
。噢,只是为了删除p
。我不熟悉返回语法并得到一个错误:错误:表“p”第9行的子句条目中缺少:返回p.tracture\u id、p.user\u id、geom
。Ohh,只需删除p
。为什么需要在TG.user\u id=TG2.user\u id和TG.tracture\u id
?您需要检查每个用户的tracture\u id与另一个用户的匹配。所以我制作了临时表。为什么需要在TG.user\u id=TG2.user\u id和TG.tracture\u id
上将tracture\u geom作为TG2连接起来?您需要检查每个用户的tracture\u id与另一个用户的匹配。所以我做了临时表。