我们有一个数据处理应用程序,它有两条独立的路径,最终应该会产生相似的结果。我们还有一个数据库支持的监控服务,可以比较和利用这个处理的结果。在任何时间点,两条路径中的任何一条都可能会或可能不会产生操作结果,但我希望能够查询一个视图,该视图告诉我已产生的任何结果。
这是我开始使用的架构的简化示例:
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
这样做的问题是 Sql Server 总是选择扫描LeftResult 和 RightResult 上的 PK 而不是seek,即使对视图的查询包括 DateId 和 EntityId 作为谓词。这似乎是由于 isnull() 检查结果。(我什至尝试过使用索引提示和forceseek,但无济于事——查询计划仍然显示扫描。)
但是,我不能简单地替换 isnull() 结果,因为连接中可能缺少左侧或右侧(因为关联的进程尚未填充表)。
我并不特别想在视图的所有消费者之间复制 MaxValue 逻辑(实际上,它的计算要复杂得多,但同样的想法也适用。)
是否有一个好的策略可以用来构建这个视图或针对它的查询,以便查询计划将使用搜索而不是扫描?