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

テーブルのようなツリーのIDと子孫を使用して2つのテーブルを結合します

    クエリの統合

    いくつかの場所でロジックを改善することで、操作全体を1つのクエリに統合できます。 SQL関数へのラップはオプションです:

    CREATE OR REPLACE FUNCTION f_elems(_action_id integer)
      RETURNS SETOF integer AS
    $func$
       WITH RECURSIVE l AS (
          SELECT a.category_id, l.local_id
          FROM   action a
          JOIN   local  l USING (local_id)
          WHERE  a.action_id = $1
    
          UNION ALL 
          SELECT l.category_id, c.local_id
          FROM   l
          JOIN   local c ON c.parent_id = l.local_id  -- c for "child"
          )
       SELECT e.element_id
       FROM   l
       JOIN   element e USING (category_id, local_id);
    $func$  LANGUAGE sql STABLE;
    

    すべてのelement_idを取得します 特定のaction_idの同じローカルおよび子ローカルの場合 。

    電話:

    SELECT * FROM f_elem(3);
    
    element_id
    -----------
    6
    7
    

    db <> fiddle こちら
    OLD sqlfiddle

    これは実質的に必要です いくつかの理由ですでに速くなっています。最も明白なものは次のとおりです:

    • plpgsqlの低速ループを純粋なSQLに置き換えます。
    • 再帰クエリの開始セットを絞り込みます。
    • 不要で悪名高いINを削除します 構築します。

    SELECT * FROM ...で呼び出しています SELECTだけでなく 、行に列が1つしかない場合でも、OUTの列名を取得します パラメータ(element_id )関数ヘッダーで宣言しました。

    もっと速く、まだ

    インデックス

    action.action_idのインデックス 主キーによって提供されます。

    ただし、local.parent_idのインデックスを見逃している可能性があります 。その間、複数列のインデックスをカバーするようにします。 (Postgres 9.2 +)with parent_id 最初の要素およびlocal_idとして 2番目として。テーブルがlocalの場合、これは大いに役立つはずです。 大きい。小さなテーブルではそれほど多くないか、まったくない:

    CREATE INDEX l_mult_idx ON local(parent_id, local_id);
    

    なんで?参照:

    最後に、複数列のインデックス テーブルのelement もう少し役立つはずです:

    CREATE INDEX e_mult_idx ON element (category_id, local_id, element_id);
    

    3番目の列element_id カバーインデックスにする場合にのみ役立ちます 。クエリがテーブルelementからさらに列を取得する場合 、インデックスに列を追加するか、element_idを削除することをお勧めします 。どちらかが速くなります。

    マテリアライズドビュー

    場合 テーブルは更新をほとんどまたはまったく受信せず、すべてのペアの事前計算されたセットを提供するマテリアライズドビュー(action_id, element_id) 同じカテゴリを共有すると、これは超高速になります 。 (action_id, element_id)を作成します (この順序で)主キー。




    1. PHPMYSQLグループランキングクエリ

    2. mysqlストアドプロシージャパラメータを一覧表示する方法

    3. Oracle PL/SQLオブジェクトのスーパーメソッドを呼び出す方法

    4. Hibernate:インデックスを作成する