PostgreSQL:这是因为锁(行级)吗?

时间:2012-07-31 15:14:13

标签: database postgresql geospatial postgis postgresql-9.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实例来使用其他核心(因为请求来自单个用户?)。
  • 这是因为锁(行级)?
  • 如何规避这个?

P.S。我很确定这将作为主题关闭。但是,我必须寻找答案。

1 个答案:

答案 0 :(得分: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 || ')');

(假设能给你正确的结果)