1

我有一张包含大约 210 万个元组的表。其中有纬度和经度列。我正在尝试将其转换为地理类型(带有 SRID 的点)。

我写的函数(过程)在我限制条目时工作正常(比如:)SELECT id,longitude,latitude FROM list_of_location limit 50

CREATE OR REPLACE FUNCTION convertlatlon() RETURNS VOID AS $$
DECLARE rec RECORD;
BEGIN
    FOR rec IN SELECT id,longitude,latitude FROM list_of_location
    LOOP
    UPDATE list_of_location SET location= concat('SRID=4326;POINT(',rec.longitude,' ',rec.latitude,')') WHERE id=rec.id;    
    END LOOP;
END;
$$ LANGUAGE 'plpgsql' ;

  • 当我尝试在整个表上运行它时,PostgreSQL 似乎什么也没做。已经等了一个半小时。
  • 消耗它正在运行的内核上 99% 的 CPU。
  • 不会弹出任何其他 PostgreSQL 实例来利用其他内核(因为请求来自单个用户?)。
  • 这是因为锁(行级别)吗?
  • 如何规避这一点?

PS我很确定这将作为题外话关闭。但是,我必须寻找答案。

4

1 回答 1

4

我不知道是什么原因造成的,但听起来可能在此操作中获得了锁。您可以轻松地验证这一点:

SELECT * FROM pg_locks;

将告诉您当前使用了哪些锁。和

SELECT * FROM pg_stat_activities WHERE waiting;

会告诉你,如果有锁,哪些事务正坐在那里空闲等待释放锁。那应该为您指明正确的方向。

不会弹出任何其他 PostgreSQL 实例来利用其他内核(因为请求来自单个用户?)。

这就是 postgres 的工作方式。单个会话将分拆一个后端。单个查询不做任何排序多进程或并发操作。

如何规避这一点?

你为什么要循环?我认为你可以一口气做到这一点。为什么不这样做:

UPDATE list_of_location 
SET location = ST_GeogFromText('POINT(' || longitude || ' ' || latitude || ')');

(假设这会给你正确的结果)

于 2012-07-31T15:59:59.280 回答