2012-08-09 4 views
31

PL/pgSQLで関数を書いていますが、行が存在するかどうかを調べる最も簡単な方法を探しています。
今はintegerbooleanに選択していますが、これは実際には機能しません。私はこれを行う最良の方法を知るのにまだ十分なPL/pgSQLを経験していません。PL/pgSQL行の存在を確認する

は、ここに私の機能の一部です:

DECLARE person_exists boolean; 
BEGIN 

person_exists := FALSE; 

SELECT "person_id" INTO person_exists 
    FROM "people" p 
WHERE p.person_id = my_person_id 
LIMIT 1; 

IF person_exists THEN 
    -- Do something 
END IF; 

END; $$ LANGUAGE plpgsql; 

アップデート - 私は今のところ、このような何かをやっている:

DECLARE person_exists integer; 
BEGIN 

person_exists := 0; 

SELECT count("person_id") INTO person_exists 
    FROM "people" p 
WHERE p.person_id = my_person_id 
LIMIT 1; 

IF person_exists < 1 THEN 
    -- Do something 
END IF; 

答えて

90

簡潔で短く、速く:EXISTSです。

IF EXISTS (SELECT 1 FROM people WHERE person_id = my_person_id) THEN 
    -- do something 
END IF; 

問い合わせプランナが見つかった最初の行で停止することができる - count()とは対照的に関係なく、全て一致する行をスキャンしました。大きなテーブルとの違いを作り出します。一意の列の条件ではほとんど問題はありません。とにかく1行だけが修飾されます(また、すぐに検索するインデックスがあります)。

以下のコメントの@a_horse_with_no_nameからの入力で改善されました。

+0

良い点! (person_idはおそらくプライマリキーなので、インデックスルックアップを使用して単一のテーブルを "スキャン"するだけです)。 –

+0

@a_horse_with_no_name:現在(PostgreSQL 9.1) 'count()' *は常に逐次スキャンをトリガします。テーブルで 'EXPLAIN ANALYZE SELECT count(id)from tbl'を試してみてください。 [Postgres Wikiの遅いカウント]に関する詳細(http://wiki.postgresql.org/wiki/Slow_Counting) Postgres 9.2の新しいインデックスのみのスキャンは、(いくつかの条件を指定して) 'count(id)'のインデックススキャンを利用することができるため、改善することになっていますが、まだ試してみる必要があります。 –

+3

A条件付きの 'count(*)' * *(特にPK列にない)は、逐次スキャンを開始しません**。 –

2

使用回数(*)

declare 
    cnt integer; 
begin 
    SELECT count(*) INTO cnt 
    FROM people 
    WHERE person_id = my_person_id; 

IF cnt > 0 THEN 
    -- Do something 
END IF; 

を編集します(ダウンボッター用誰が文を読んでいないと、列(及び列の名前にwhere句があるため、解決策はだけ効果がある

似た何かを)やっているかもしれない他の人がその主キーことを示唆しています - where句が非常に有効です)

そのため、where句のために、主キーで識別される行の存在をテストするためにLIMITなどを使用する必要はありません。 で、これをテストする有効な方法です。

+0

私はあなたがこれを投稿したときに私の投稿にこの解決策を追加しました。 – nnyby

+2

この目的のためにCOUNTを使用しないでください。パフォーマンス上の問題です。または、派生テーブルSELECT COUNT(*)FROM(SELECT * FROM people LIMIT 1)x –

+1

@PavelStehuleを使用する必要があります。 **プライマリキー**?私はそれがおそらくあなたの声明よりもはるかに遅くなるだろうと想像することはできません。実行計画は、両方のソリューションでほぼ同じです。 –

関連する問題