SQL 查看执行顺序
SQL View order of execution
我需要澄清 where 子句的执行如何围绕视图工作。我的视图为每个项目调用函数,并且其中有一个仅用于活动项目的 where 子句。如果我的表 1 有 1 M 条记录,下面是我的观点....
Create View vwTable1 as
select
t2.Name as table1Name,
t2.ItemId as table1Id,
dbo.GetTimezone(t2.ItemId) as TimeZoneKey,
t2.AlternateId, t2.Created,t2.ParentKey,
t1.table1TypeKey,
t3.English_US as table1TypeKeyName,
from
table1 as t1
join
Item as t2 on t1.table1Id = t2.ItemId
join
vwEnumValue as t3 on t3.EnumValueId = t1.[table1TypeKey]
where
dbo.GetInheritedStatus(t2.ItemId) in (1, 2)
当我写这样的查询时
Select *
From vwTable1
Where ItemId = 14..
我的理解是视图会
- 仅 运行 用于 ItemId = 14 的一条记录....
- 然后将仅为该项目 14 调用 GetTimezone....
- 只检查 14 项的 GetInheritedStatus。
对吗?
否则会执行
- Select 所有 100 万条记录的名称,GetTimeZone(),
- 然后从中获取继承状态为 1 或 2 的所有项目....
- 然后会选择ItemID =14.
这个执行顺序有很大的不同。基本上我认为这是一个像
这样的大查询
Select *
from
(Select
t2.Name as table1Name,
t2.ItemId as table1Id,
dbo.GetTimezone(t2.ItemId) as TimeZoneKey,
t2.AlternateId, t2.Created,t2.ParentKey,
t1.table1TypeKey,
t3.English_US as table1TypeKeyName,
from
table1 as t1
join
Item as t2 on t1.table1Id = t2.ItemId
join
vwEnumValue as t3 on t3.EnumValueId = t1.[table1TypeKey]
where
dbo.GetInheritedStatus(t2.ItemId) in (1, 2) )
where
ItemId = 14
对于所有 1 M 条记录,内部 select 是否先行然后它的 where 子句或外部 Select 仅在 ItemId = 14 时先行。
谢谢
My understanding is that the view will 1) ONLY run for one record...
没有
SQL 是一种 声明式 语言,而不是 命令式 语言。这意味着数据库引擎可以自由地执行任何操作以检索您请求的信息,引擎确定它 "better" 可以这样做。
更好 部分很棘手。通常 SQL 语句在解析后会被改写。然后 SQL 规划器会产生许多可能的计划来执行它,最后 SQL 优化器会选择其中一个计划。
哪一个?这取决于多种因素:
- 表格类型。
- 访问操作的全部内容。
- 您在表中的索引。
- 数据直方图。
- 您在查询中应用的选择过滤器。
- 等等
此外,您还可以轻松获取查询的执行计划。然而,这并不意味着该计划在未来会保持不变。明天,SQL 优化器可能会根据上述任何值的变化选择不同的计划。甚至可能对数据库进行新的更新也会向数据库引擎添加新的操作。
我需要澄清 where 子句的执行如何围绕视图工作。我的视图为每个项目调用函数,并且其中有一个仅用于活动项目的 where 子句。如果我的表 1 有 1 M 条记录,下面是我的观点....
Create View vwTable1 as
select
t2.Name as table1Name,
t2.ItemId as table1Id,
dbo.GetTimezone(t2.ItemId) as TimeZoneKey,
t2.AlternateId, t2.Created,t2.ParentKey,
t1.table1TypeKey,
t3.English_US as table1TypeKeyName,
from
table1 as t1
join
Item as t2 on t1.table1Id = t2.ItemId
join
vwEnumValue as t3 on t3.EnumValueId = t1.[table1TypeKey]
where
dbo.GetInheritedStatus(t2.ItemId) in (1, 2)
当我写这样的查询时
Select *
From vwTable1
Where ItemId = 14..
我的理解是视图会
- 仅 运行 用于 ItemId = 14 的一条记录....
- 然后将仅为该项目 14 调用 GetTimezone....
- 只检查 14 项的 GetInheritedStatus。
对吗?
否则会执行
- Select 所有 100 万条记录的名称,GetTimeZone(),
- 然后从中获取继承状态为 1 或 2 的所有项目....
- 然后会选择ItemID =14.
这个执行顺序有很大的不同。基本上我认为这是一个像
这样的大查询Select *
from
(Select
t2.Name as table1Name,
t2.ItemId as table1Id,
dbo.GetTimezone(t2.ItemId) as TimeZoneKey,
t2.AlternateId, t2.Created,t2.ParentKey,
t1.table1TypeKey,
t3.English_US as table1TypeKeyName,
from
table1 as t1
join
Item as t2 on t1.table1Id = t2.ItemId
join
vwEnumValue as t3 on t3.EnumValueId = t1.[table1TypeKey]
where
dbo.GetInheritedStatus(t2.ItemId) in (1, 2) )
where
ItemId = 14
对于所有 1 M 条记录,内部 select 是否先行然后它的 where 子句或外部 Select 仅在 ItemId = 14 时先行。
谢谢
My understanding is that the view will 1) ONLY run for one record...
没有
SQL 是一种 声明式 语言,而不是 命令式 语言。这意味着数据库引擎可以自由地执行任何操作以检索您请求的信息,引擎确定它 "better" 可以这样做。
更好 部分很棘手。通常 SQL 语句在解析后会被改写。然后 SQL 规划器会产生许多可能的计划来执行它,最后 SQL 优化器会选择其中一个计划。
哪一个?这取决于多种因素:
- 表格类型。
- 访问操作的全部内容。
- 您在表中的索引。
- 数据直方图。
- 您在查询中应用的选择过滤器。
- 等等
此外,您还可以轻松获取查询的执行计划。然而,这并不意味着该计划在未来会保持不变。明天,SQL 优化器可能会根据上述任何值的变化选择不同的计划。甚至可能对数据库进行新的更新也会向数据库引擎添加新的操作。