Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用3个FOR循环优化SQL查询_Sql_Postgresql_Query Optimization_Postgis - Fatal编程技术网

使用3个FOR循环优化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

我有一个完整的SQL查询。但是,它非常非常慢。我正在寻找一种方法来优化它

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与另一个用户的匹配。所以我做了临时表。