Oracle 階層クエリを使用して、潜在的に非常に大きなツリー構造をモデル化することを検討しています (無限の幅と 30 以上の深さの可能性があります)。私の理解では、階層クエリはSQLを再帰的に結合する方法を提供しますが、同等のクエリを手動で作成する場合に比べて、実際のパフォーマンスは向上しません...これは事実ですか? オラクルの階層クエリを使用して、パフォーマンスに関して、人々はどのような経験をしましたか?
4 に答える
簡単に言えば、階層拡張 (connect by) がなければ、再帰クエリを作成できないということです。再帰的にリンクされた多くのクエリをプログラムで発行できます。
すべてのデータベース、特にオラクルに関する経験則では、単一のクエリで結果を発行できれば、ほとんどの場合、プログラムで実行するよりも高速になります。
私の経験では、はるかに小さなセットを扱ってきたので、大規模なセットで階層クエリがどれだけうまく機能するかについては言えません。
これらのツリーの取得を行う場合、通常、次のオプションがあります
- すべてをクエリし、クライアント側でツリーを組み立てます。
- ツリーの各レベルに対して 1 つのクエリを実行し、以前のクエリ結果から必要であるとわかっているものに基づいて構築します。
- Oracleが提供する組み込みのものを使用します(START WITH、CONNECT BY PRIOR)。
データベースですべてを実行すると、不要なラウンド トリップや、大量のデータを取得する無駄なクエリが削減されます。
階層テーブル内のデータを分割してから、クエリに含まれるパーティションを制限してみてください。
CREATE TABLE
loopy
(key NUMBER, key_hier number, info VARCHAR2, part NUMBER)
PARTITION BY
RANGE (part)
(
PARTITION low VALUES LESS THAN (1000),
PARTITION mid VALUES LESS THAN (10000),
PARTITION high VALUES LESS THAN (MAXVALUE)
);
SELECT
info
FROM
loopy PARTITION(mid)
CONNECT BY
key = key_hier
START WITH
key = <some value>;
興味深い問題は、パーティショニング戦略になります。Oracle にはいくつかのオプションが用意されています。
connect by の使用が遅くなる可能性があることを見てきましたが、何と比較して? 再帰的な PL/SQL 呼び出し (遅い) を使用して結果セットを作成するか、クライアント側で実行する以外に、実際には別のオプションはありません。
データをマッピング (階層定義) とルックアップ テーブル (表示データ) に分けてから、それらを結合してみることができます。インデックス付きフィールドから階層データを取得していると仮定すると、多くの利益は期待できないと思いますが、試してみる価値があります。
connect by を使って試してみましたか?私はさまざまなバリエーションを試すのが大好きです。