我使用的是SQL Server 2008,但如果它很重要,可以使用更高版本。
我有2张表,其中有一些人的数据非常相似,但格式不同(这两组人之间没有交叉点)。
Table 1:
int personID
bit IsOldPerson //this field is indexed
Table 2:
int PersonID
int Age
我想要一个具有与表1相同结构的组合视图。所以我编写了以下脚本(简化版):
CREATE FUNCTION CombinedView(@date date)
RETURNS TABLE
AS
RETURN
select personID as PID, IsOldPerson as IOP
from Table1
union all
select personID as PID, dbo.CheckIfOld(Age,@date) as IOP
from Table2
GO
函数“CheckIfOld”返回yes / no,具体取决于@date日期的输入年龄。
所以我在这里有两个问题:
一个。如果我尝试select * from CombinedView(TODAY) where IOP=true
,SQL Server是否会单独执行以下操作:1)对于表1,使用字段IsOldPerson的索引并执行“聪明的”基于索引的结果选择; 2)对于表2,计算所有行的CheckIfOld并在计算过程中逐行拾取或拒绝行?
B中。如何检查这个特定情况下的执行计划,以了解我对问题(A)的猜测是否正确?
非常感谢任何帮助!谢谢!
答案 0 :(得分:0)
是的,如果查询不是太复杂,查询优化器应该将视图“透视”到其组成的UNION-ed SELECT语句中,单独评估它们并连接结果。如果Table1上有索引,它应该能够使用它。我使用我们拥有的表和您提供的相同功能概念对此进行了测试。我查看了原始SELECT到Table1的查询计划和使用UNION的内联表值函数的SELECT,以及与Table1相关的查询计划部分是相同的 - 它使用了索引。
现在如果考虑到表现,我建议你做两件事之一:
如果(a)Table2读取繁重而不是重写,(b)您有空格,(c)您可以将CheckIfOld写为单个CASE语句(作为其名称和上下文)问题暗示),那么你应该考虑使用IsOldPerson的计算并在其中应用索引来创建Table2中的持久计算字段。
如果Table2写入较多,或者您没有其他字段的空间,则至少应考虑将CheckIfOld转换为内联函数。根据使用方式的不同,您可能会获得性能提升。在你的情况下,它会像这样使用:
选择personID作为PID,IOP.IsOldPerson来自Table2 CROSS APPLY dbo.CheckIfOld(Age,@ date)AS IOP