現在、ネストされたセット モデルを使用して、会社の組織情報を格納するテーブルから、従業員のすべての直接および間接のマネージャーをクエリするための自己結合を含むクエリがあります。この 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 *
提案されたビューで実行すると、結果は置き換えようとしている古いテーブルとほぼ同じになります。とても。