【发布时间】:2020-06-18 05:57:59
【问题描述】:
很遗憾,我无法准备一个示例以便您可以在计算机上重复它,但我认为这对于理解问题所在没有必要。 有这样的查询:
with cte as (
select selectStations.ReceiverUID, 1907 as id
from WF4_Routes r WITH (NOLOCK)
inner join WF4_Stages selectStages WITH (NOLOCK) on selectStages.RouteID = r.ID and r.SentToCAS = 1 and r.PRUZ <> 1 and selectStages.PRUZ <> 1 and selectStages.StageType = 1
inner join WF4_Stations selectStations WITH (NOLOCK) on selectStations.ApprovalStageID = selectStages.ID and selectStations.PRUZ <> 1
)
select *--case when dbo.fnGetGkExchangeParticipantQuick(cte.ReceiverUID, id) = 'E477B8FA-7539-4B43-8961-807A29FECFC0' then 1 else 0 end
from cte
where dbo.fnGetGkExchangeParticipantQuick(cte.ReceiverUID, id) = 'E477B8FA-7539-4B43-8961-807A29FECFC0'
从整个脚本来看,在“where”条件下调用标量函数和在“select”中被注释掉的调用很重要。
CREATE FUNCTION [dbo].fnGetGkExchangeParticipantQuick(@CurrentUID uniqueidentifier, @IsExchangeParticipantAttrID int)
RETURNS uniqueidentifier
AS
BEGIN
declare @UnitUID uniqueidentifier
select @UnitUID = UID from GL_OBJECTS where UID = @CurrentUID and ACTIVE = 1
while @UnitUID is not null
begin
if (select top 1 cast(PropertyValue as bit) from MB_ATTRIBUTES_TO_VALUES where Object_UID = @UnitUID and Attribute_ID = @IsExchangeParticipantAttrID) = 1
break;
set @UnitUID = null
select @UnitUID = PARENT from GL_OBJECTS where UID = @UnitUID and ACTIVE = 1
end
return @UnitUID
END
GO
该函数从对象层次结构中的父级中搜索特定属性。
如果我在“where”条件下调用这个函数,那么查询将在 1 秒内执行,同时从磁盘读取大约 60 万条记录。如果我在“选择”条件下调用这个函数,那么这个函数会在 10 毫秒内执行,从磁盘读取的次数为 30。
如果您查看计划,您可以看到由于某种原因调度程序用“where”条件满足“with”条件,即他正在尝试优化组合条件的执行,我不需要它.我试图将分组添加到“with”条件或“distinct”条件没有帮助。
请帮助我了解问题所在?
【问题讨论】:
-
您的评论帮助我提出了将函数移至“with”块的建议。这似乎是我的问题的解决方案。
-
注意:你不应该使用
nolock,除非你必须这样做,因为结果是不可预测的。
标签: sql-server tsql