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は何もしないようです。1時間半待っています。
  • 実行中のコアでCPUの99%を消費します。
  • 他のコアを利用するためにPostgreSQLの他のインスタンスを起動しません(要求は単一のユーザーからのものであるため?)。
  • これはロック(行レベル)が原因ですか?
  • これを回避する方法は?

PS私はこれがオフトピックとして閉じられるとかなり確信しています。しかし、私は答えを探さなければなりません。

4

1 に答える 1

4

何が原因かわかりませんが、この操作でロックが取得された可能性があります。ただし、これは簡単に確認できます。

SELECT * FROM pg_locks;

現在取得されているロックを教えてくれます。と

SELECT * FROM pg_stat_activities WHERE waiting;

ロックがある場合、どのトランザクションがロックが解放されるのを待ってアイドル状態になっているのかがわかります。それはあなたを正しい方向に向けるべきです。

他のコアを利用するためにPostgreSQLの他のインスタンスを起動しません(要求は単一のユーザーからのものであるため?)。

これがpostgresの仕組みです。1つのセッションで1つのバックエンドがスピンオフします。単一のクエリは、ソートマルチプロセスまたは並行操作を実行しません。

これを回避する方法は?

なぜループしているのですか?これは一発でできると思います。してみませんか:

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

(それがあなたに正しい結果を与えると仮定して)

于 2012-07-31T15:59:59.280 に答える