2012-12-01 6 views
5

データをプルできるようになりましたが、大きなデータセットに対してクエリを最適化するより良い方法があるかどうかは疑問です。階層クエリで子、親、兄弟を引き出す必要がある

http://sqlfiddle.com/#!4/0ef0c/5

だから基本的に私は、クエリに与えられた組織IDを供給できるようにしたいし、それが再帰的にその親、子、兄弟とその叔母と叔父を引き出しています。その組織階層に関連付けられているアクティビティをすべて取得します。

Org1はトップレベルの組織ですが、nullの親がある場合とない場合があります。

基本的に私は子供と親を引っ張るために上下のクエリを行っていましたが、別のクエリを追加することによって兄弟を得ることができます。最後に、友人の助けを借りて別のクエリを取得しましたが、大量のデータセット(アクティビティの4〜5k)は非常に低いです。

洞察力があれば幸いです。

+0

フィドル作成の問題が発生した場合は、リンクが便利です。 – Laurence

+0

申し訳ありません。 http://sqlfiddle.com/#!4/5310d/5/0 –

+0

ええ、それは明確にするのに役立ちます。従って、あなたが引っ張ってほしいものに新しい情報を追加したのは3回目です。忘れてください。 – REW

答えて

0

組織が構造が厳密に階層的である場合、このアプローチを使用できます。 http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html

欠点は、組織構造のすべての更新時にインデックスを更新する必要があることです。しかし、org構造は通常より頻繁に読み取られ、次に変更されます。だからIMHOこれはトリックを行う必要があります。

0

これを行うための鍵は、「再帰的に」という言葉にあります。これを行うには、それ自身を呼び出すプロシージャを作成します。これは親の例ですが、エントリをスクロールするためにカーソルを使用しているため、これを使用して再帰を含む子やその他の関係を見つける方法は簡単です。

CREATE OR REPLACE PROCEDURE find_parents( 
    org_id NUMBER, 
    lvl NUMBER DEFAULT 1) AS 

    c_parent table1.id%TYPE; 
    c_name table1.name%TYPE; 
    CURSOR c_parents (c_id table1.id%TYPE) IS 
    SELECT parent, name FROM table1 WHERE (id = c_id); 

    BEGIN 
    dbms_output.put('-'); 
    OPEN c_parents(org_id); 
    LOOP 
     FETCH c_parents INTO c_parent, c_name; 
     EXIT WHEN c_parents%notfound; 
     dbms_output.put_line('Level ' || lvl || ' parent: [ID: ' || c_parent || ', NAME: ' || c_name || ']'); 
     find_parents(c_parent, lvl + 1); 
    END LOOP; 
    CLOSE c_parents; 
    END; 
+0

これは、規則的な階層的クエリで実行可能である必要があります。手順は必要ありません。 –