如果不清楚我对这个问题的意思,我已经完整地举了这个问题。
我做了一个视图,它连接了大约五个表的数据。这些表有大量数据,查询运行缓慢。我的问题是,如果我这样做:
SELECT * FROM myView WHERE PersonID = 1000
SQL Server'知道我的意思'并自动将该条件传播到视图中的基础连接吗?因此它不会为每个人运行,但会在最合适的阶段最小化结果集。或者它会运行所有内容然后在完整结果集上执行WHERE ID = 1000
吗?
示例
为了简化(...希望)我的意思,这是一个伪TSQL场景示例:
TABLE People (
ID,
Surname,
DOB
)
TABLE Activities (
ID,
TypeID,
LocationID,
Date
)
TABLE PersonActivityInvolvements (
ID,
PersonID,
ActivityID
)
TABLE ActivityTypes (
ID,
Name
)
TABLE Locations (
ID,
Street,
City
)
所以我想要一个视图,向我显示所有People
,他们参与的任何Activities
,ActivityType
和Location
。虽然这种设置并不是非常复杂,但你可以看到,如果每个实体都有数万个实体可能需要很长时间才能执行。
视图可能是这样的:
SELECT
*
FROM
People LEFT OUTER JOIN PersonActivityInvolvement PA
ON People.ID = PA.ID
INNER JOIN Activity
ON PA.ID = Activity.ID
INNER JOIN ActivityTypes AT
ON A.TypeID = AT.ID
INNER JOIN Locations
ON A.LocationID = Locations.ID
所以,如果要做的话
SELECT * FROM myView WHERE DOB >= dateAdd(YEAR, -18, getDate())
视图中的查询是否会为每个人运行,或者SQL Server是否知道它应该将其应用于People.DOB
字段?
答案 0 :(得分:3)
通常,优化器将使用aplomb处理此问题,但随着查询和隐含子查询变得越来越复杂,优化器选择正确执行路径的可能性也会相应减少。通过在表上添加更多索引或者将要检查的表上的索引非常相似,可能会加剧这种情况。
作为一般规则,我试图阻止加入观点,我强烈反对创建由其他观点组成的观点。
答案 1 :(得分:2)
答案 2 :(得分:1)
引擎会做任何它认为最快的事情。如果您已将该字段编入索引,并且您的JOIN
密钥都已编入索引,则可能首先运行或不运行该过滤器。
如果WHERE
子句更昂贵(即无索引),它实际上可能会运行过滤器LAST - 这样就会在最小的结果集上运行昂贵的操作。
确定的唯一方法是运行查询并检查执行计划( ACTUAL 未估算)。