1

現在、ネストされたセット モデルを使用して、会社の組織情報を格納するテーブルから、従業員のすべての直接および間接のマネージャーをクエリするための自己結合を含むクエリがあります。この SQL 表記では、コロンが前に付いている数字 (例: :1) は変数です。

select parent.empid, parent.depth from RelationshipMgr as node join
RelationshipMgr as parent on node.lft between parent.lft and parent.rgt
and node.empid = :1 order by parent.lft

結合条件または where 句のいずれかに追加することで、従業員のnレベル上のマネージャーの ID のみを簡単に返すことができます(副次的な質問: どちらが速いですか?)。parent.depth = node.depth - :2

問題:このクエリをビューに変換しようとしていますが、うまくいきません。問題は、ほとんどまたはすべての変数がクエリの結合条件に含まれていることです。私の現在の最善の計画は、これらの部分を列に分割して、ビューをクエリするときに where 句を使用できるようにすることです。たとえば、次のようになります。

select node.EmpID, parent.empid as MgrID, parent.depth as MgrDepth,
node.depth - parent.depth as MgrRelativeAltitude from RelationshipMgr as node
join RelationshipMgr as parent on node.lft between parent.lft and parent.rgt

従業員のnMgrRelativeAltitudeレベル上のマネージャーの ID を見つけることができる列を発明しなければならなかったことがわかりますが、それはほとんど最大の問題ではありません。SQL Server は結合条件で指定されたとおりに完全な結合を実行し、where 句を使用して結合を制限するのではなく、where 句でフィルター処理するように見えるため、これにより深刻なパフォーマンスの問題が発生するのではないかと心配しています。 ビューを作成するより良い方法はありますか? これをクエリとして残し、ビューの作成を忘れるべきですか? ビューではなくストアド プロシージャにすることで、何かメリットがありますか?

そして、「時期尚早の最適化は悪だ」とは言わないでください...それは時期尚早ではありません。私が置き換えようとしている実装は、従業員を直接および間接のマネージャーの 1 人に関連付けるレコードを持っていた粗末な隣接リストのようなものを使用していました... 最悪の場合、O(n^2) レコードであり、予想通り重大なパフォーマンスの問題に遭遇しました。階層には約 300,000 人以上の従業員がいました。私の新しいネストされたセットの実装は、この1つのクエリを除いて、これらのパフォーマンスの問題を軽減します...select *提案されたビューで実行すると、結果は置き換えようとしている古いテーブルとほぼ同じになります。とても。

4

1 に答える 1

0

隣接していないノードの階層関係を特定しようとしています。お気づきのように、これは比較的コストのかかるランタイム計算、ビュー、または通常のクエリです。代わりに、頻繁に実行する場合は、ブリッジ テーブルと呼ばれるものを作成することをお勧めします。トリガーを介して更新される実際のテーブルとして、または SQL Server 2005+ のインデックス付きビューとして (ただし、インデックス付きビューのアプローチは試していません)。とにかく、ネストされたセットは、隣接リストと比較して優れた読み取り時間を提供します。

トレードオフは、ノードが追加、削除、または親 ID が変更されるたびに更新されるため、すべてのノード間の関係を効果的に表すため、ソースよりもはるかに多くの行を持つテーブルです。その見返りに、インデックスを作成して取得時間を短縮できます。ブリッジを更新すると、ブリッジが頻繁に実行される入力の組み合わせのキャッシュとして機能するが、実行時にまれなケースを計算するストアド プロシージャを介してこれにアクセスしていることがボトルネックであることが判明した場合の最適化。その決定を行うには、基になるノード テーブルの読み取りと書き込みの頻度を評価する必要があります。

RDBMS で階層データを表すためのオプションの概要については、こちらを参照してください

于 2011-02-02T15:29:24.613 に答える