我有两个Server 2019实例,一个在客户站点,一个在我们的实验室。一个函数调用确定一个执行触发器是最后一个(或者不是最后一个)触发器,它在站点和实验室产生了非常不同的执行计划,性能有很大的不同。函数调用定义是从web中剽窃的,完全基于下面定义的系统表、系统调用和ObjectProperty,而不是任何用户定义的表。
两个实例上的数据库模式完全相同。那么,优化器为什么要创建两个不同的计划呢?这是现场的计划
这是我实验室机器的计划
站点中的计划xml引用了几个基本表,如sysclsobjs、sysschobjs、sysowners、sysclsobjs,这些表具有非常老的统计数据,而实验室中的计划xml没有引用这些表。为什么计划引用这些奇怪的表,这对性能问题有任何影响?在实验室和站点中,服务器或数据库选项是否可能略有不同?任何指南针都会赏识。如果有帮助,我可以附加计划XML和函数定义。
更新1。
发布于 2022-10-28 09:59:00
我猜您的主要问题实际上是您使用的是兼容性视图,比如sysobjects
,而不是更新的sys.objects
等等。
在大型查询中使用系统功能也是一个问题,因为它们最终可能会被大量执行。最好是加入正确的桌子。
您可以使用以下更新的代码,希望这将给您提供更好的性能。
sysusers
sys.tables
和sys.schemas
似乎也没有为查询做任何事情,所以我已经删除了它们。
CREATE OR ALTER FUNCTION dbo.fn_HasRegularMQTriggerFinishedExecuting (@TriggerId int)
RETURNS INT
AS
BEGIN
DECLARE @parent_id int = (
SELECT tr_other.parent_id
FROM sys.triggers tr_other
WHERE tr_other.object_id = @TriggerId
);
RETURN CASE WHEN EXISTS (SELECT 1
FROM sys.triggers tr
WHERE tr.is_disabled = 0
AND tr.parent_id = @parent_id
AND EXISTS (SELECT 1
FROM sys.trigger_events te
WHERE te.object_id = tr.parent_id
--Filter only for triggers which are not last triggers
AND te.is_last = 0
)
AND TRIGGER_NESTLEVEL(tr.parent_id, 'AFTER', 'DML') > 0
)
THEN 0
ELSE 1
END;
END;
https://dba.stackexchange.com/questions/318809
复制相似问题