最終的に同様の結果を生成する 2 つの個別のパスを持つデータ処理アプリケーションがあります。また、この処理結果を比較・活用するデータベースによる監視サービスもご用意しております。任意の時点で、2 つのパスのいずれかが操作の結果を生成する場合と生成しない場合がありますが、生成された結果について通知するビューを照会できるようにしたいと考えています。
以下は、私が始めたスキーマの簡単な例です。
create table LeftResult (
DateId int not null,
EntityId int not null,
ProcessingValue int not null
primary key ( DateId, EntityId ) )
go
create table RightResult (
DateId int not null,
EntityId int not null,
ProcessingValue int not null
primary key ( DateId, EntityId ) )
go
create view CombinedResults
as
select
DateId = isnull( l.DateId, r.DateId ),
EntityId = isnull( l.EntityId, r.EntityId ),
LeftValue = l.ProcessingValue,
RightValue = r.ProcessingValue,
MaxValue = case
when isnull( l.ProcessingValue, 0 ) > isnull( r.ProcessingValue, 0 )
then isnull( l.ProcessingValue, 0 )
else isnull( r.ProcessingValue, 0 )
end
from LeftResult l
full outer join RightResult r
on l.DateId = r.DateId
and l.EntityId = r.EntityId
go
これに関する問題は、ビューへのクエリに DateId と EntityId が述語として含まれている場合でも、 Sql Server は常にseekではなく LeftResult と RightResult で PKをスキャンすることを選択することです。これは、結果に対する isnull() チェックによるものと思われます。(インデックス ヒントと forceseek を使用してみましたが、役に立ちませんでした。クエリ プランはまだスキャンを示しています。)
ただし、isnull() の結果を単純に置き換えることはできません。これは、左側または右側のいずれかが結合から欠落している可能性があるためです (関連するプロセスがまだテーブルに入力されていないため)。
ビューのすべてのコンシューマーで MaxValue ロジックを特に複製したくはありません (実際には、これはかなり複雑な計算ですが、同じ考え方が当てはまります)。
クエリ プランがスキャンではなくシークを利用するように、このビューまたはそれに対するクエリを構築するために使用できる優れた戦略はありますか?