sql-server – SCHEMABINDING万圣节保护之外的功能有什么好处?
|
众所周知,SCHEMABINDING函数可以在更新计划中使用 avoid an unnecessary spool:
即使它不访问数据,SCHEMABINDING函数还有其他优点吗? 解决方法是.未指定WITH SCHEMABINDING意味着SQL Server会跳过它通常在函数体上进行的详细检查.它只是将函数标记为访问数据(如问题中给出的链接中所述). 这是性能优化.如果它没有做出这个假设,SQL Server将不得不对每个函数调用执行详细检查(因为未绑定的函数可能随时更改). 有五个重要的功能属性: >决定论 例如,采用以下未绑定的标量函数: CREATE FUNCTION dbo.F
(
@i integer
)
RETURNS datetime
AS
BEGIN
RETURN '19000101';
END;
我们可以使用元数据函数查看五个属性: SELECT
IsDeterministic = OBJECTPROPERTYEX(Func.ID,'IsDeterministic'),IsPrecise = OBJECTPROPERTYEX(Func.ID,'IsPrecise'),IsSystemVerified = OBJECTPROPERTYEX(Func.ID,'IsSystemVerified'),UserDataAccess = OBJECTPROPERTYEX(Func.ID,'UserDataAccess'),SystemDataAccess = OBJECTPROPERTYEX(Func.ID,'SystemDataAccess')
FROM (VALUES(OBJECT_ID(N'dbo.F',N'FN'))) AS Func (ID);
两个数据访问属性已设置为true,其他三个设置为false. 这超出了可能预期的含义(例如,在索引视图或索引计算列中使用). 对查询优化器的影响 Determinism属性尤其会影响查询优化器.它有关于允许执行的重写和操作类型的详细规则,并且这些规则对于非确定性元素非常有限.副作用可能非常微妙. 例如,请考虑以下两个表: CREATE TABLE dbo.T1
(
SomeInteger integer PRIMARY KEY
);
GO
CREATE TABLE dbo.T2
(
SomeDate datetime PRIMARY KEY
);
…以及使用该函数的查询(如前所述): SELECT *
FROM dbo.T1 AS T1
JOIN dbo.T2 AS T2
ON T2.SomeDate = dbo.F(T1.SomeInteger);
查询计划符合预期,其特征是搜索表T2: 但是,如果使用派生表或公用表表达式编写相同的逻辑查询: WITH CTE AS
(
SELECT *,dt = dbo.F(T1.SomeInteger)
FROM dbo.T1 AS T1
)
SELECT *
FROM CTE
JOIN dbo.T2 AS T2
ON T2.SomeDate = CTE.dt;
-- Derived table
SELECT
*
FROM
(
SELECT *,dt = dbo.F(T1.SomeInteger)
FROM dbo.T1 AS T1
) AS T1
JOIN dbo.T2 AS T2
ON T2.SomeDate = T1.dt;
执行计划现在具有扫描功能,其中谓词涉及功能卡在过滤器中: 如果派生表或公用表表达式被视图或内联函数替换,也会发生这种情况. FORCESEEK提示(和其他类似的尝试)将不会成功: 根本问题是查询优化器无法自由地重新排序非确定性查询元素. 要生成搜索,需要将Filter谓词向下移动到T2数据访问.当函数是非确定性时,将阻止此移动. 固定 此示例的修复包括两个步骤: >添加WITH SCHEMABINDING 第一步是微不足道的.第二个涉及从字符串到日期时间删除非确定性隐式转换;用确定的CONVERT替换它.它本身都不够. ALTER FUNCTION dbo.F
(
@i integer
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
-- Convert with a deterministic style
RETURN CONVERT(datetime,'19000101',112);
END;
功能属性现在是: 随着优化器的释放,所有示例现在都可以生成所需的搜索计划. 请注意,在函数中使用CAST到datetime不起作用,因为无法在该语法中指定转换样式: ALTER FUNCTION dbo.F
(
@i integer
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
-- Convert with a deterministic style
RETURN CAST('19000101' AS datetime);
END;
此函数定义生成扫描计划,属性显示它仍然是不确定的: (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
