我正在MS上实现行级锁定。我在下面创建的函数可以工作,但是即使使用非常小的数据集,返回结果也需要相当长的时间。
例如,如果我要在VBA中对其进行编码,我将只调用username()函数一次,并存储结果。这能在表值函数中完成吗?
CREATE Function [compliance].[fn_AllowActivity] (@ActivityID sysname)
returns table
with schemabinding
as
return select 1 as [fn_AllowActivity_result]
from
compliance.tbl_Users join compliance.tbl_Activity on compliance.tbl_Users.UnitID=compliance.tbl_Activity.UnitID
where @ActivityID=compliance.tbl_Activity.ActivityID and compliance.tbl_Users.Active=1 and compliance.tbl_Users.Windows_ID=substring(user_name(),CHARINDEX('\',user_name())+1,10)
or compliance.tbl_Users.Windows_ID = substring(user_name(),CHARINDEX('\',user_name())+1,10) and compliance.tbl_Users.Active=1 and compliance.tbl_Users.RoleID>=3
GO发布于 2021-09-19 08:15:06
除了索引(这很重要)之外,还可以通过将用户名存储在变量中并在联接中添加用户名条件来改进查询,这将简化查询并提高连接性能:
CREATE Function [compliance].[fn_AllowActivity] (@ActivityID sysname)
RETURNS TABLE
WITH schemabinding
AS
DECLARE @UserName VARCHAR(250) = SUBSTRING(user_name(), CHARINDEX('\', user_name() ) + 1 , 10)
RETURN SELECT 1 AS [fn_AllowActivity_result]
FROM
compliance.tbl_Users
JOIN compliance.tbl_Activity
ON compliance.tbl_Users.UnitID = compliance.tbl_Activity.UnitID
AND compliance.tbl_Users.Windows_ID = @UserName
AND compliance.tbl_Users.Active = 1
WHERE
@ActivityID = compliance.tbl_Activity.ActivityID
AND compliance.tbl_Users.Active = 1
OR compliance.tbl_Users.RoleID >= 3
GO发布于 2021-09-09 12:23:33
根据Pavlov的评论,我在表中添加了索引,并修改了功能如下:
ALTER Function [compliance].[fn_AllowActivity] (@ActivityID sysname)
returns table
with schemabinding
as
return select 1 as [fn_AllowActivity_result]
from
compliance.tbl_Users left join compliance.tbl_Activity on compliance.tbl_Users.UnitID=compliance.tbl_Activity.UnitID
where compliance.tbl_Users.Active=1 and compliance.tbl_Users.Windows_ID = substring(user_name(),CHARINDEX('\',user_name())+1,10) and
(@ActivityID=compliance.tbl_Activity.ActivityID or compliance.tbl_Users.RoleID>=3)
GO性能现在在预期的范围内。非常感谢!
https://codereview.stackexchange.com/questions/267817
复制相似问题