sql >> データベース >  >> RDS >> PostgreSQL

Postgrespg_try_advisory_lockはすべてのレコードをブロックします

    スキャンされるセット全体の行ごとに1回pg_try_advisory_lock()を呼び出しています(whereで発生するフィルタリングの一部として) 句)、クエリによって返されるtable1の行ごとに1回だけ呼び出されるようにします。

    代わりにサブクエリまたはCTEを使用してみてください:

    with rows as (
    SELECT a.id
    FROM table1 a
    JOIN table2 b ON a.table1_id = b.id
    WHERE table2.id = 1
    )
    select rows.*
    from rows
    where pg_try_advisory_lock('table1'::regclass::integer, rows.id);
    

    ただし、必ずしも期待どおりに機能することに依存しないでください。Postgresは、最初のクエリと同じように書き直したくなるはずです。

    selectなので、もう1つの可能性はこれです。 ステートメントの一部は、クエリの非常に遅い段階で評価されます:

    with rows as (
    SELECT a.id,
           pg_try_advisory_lock('table1'::regclass::integer, a.id) as locked
    FROM table1 a
    JOIN table2 b ON a.table1_id = b.id
    WHERE table2.id = 1
    )
    select rows.id
    from rows
    where rows.locked;
    

    実際の本当の問題は、pg_try_advisory_lock() これは、あなたがしているようなクエリではなく、アプリランドや関数で通常見られるものです。そういえば、何をしているのかにもよりますが、select … for updateを使用すべきではないと確信しています。 ?

    更新について:

    はい。 limit 1のため 、一致するものを見つけてすぐに停止します。ただし、おそらく起こっているのは、whereを評価していないということです。 クエリに応じて同じ順序で句。 SQLは、a <> 0を保証するものではありません。 a <> 0 and b / a > cの一部 最初に評価されます。あなたのケースに適用され、それはアドバイザリーロックが後に取得されるという保証を提供しません aの行はbと結合されます。




    1. レポートの特徴

    2. SSRSでOracleストアドプロシージャの実行中にエラーが発生しました:PLS-00306:呼び出しの引数の数またはタイプが正しくありません

    3. InsertステートメントのPostgresでUUIDを生成しますか?

    4. SQLと一意のn列の組み合わせ