在较大的查询中使用 IF NOT EXISTS 子查询时,我遇到了显着的性能差异。子查询独立运行时执行速度很快,大约需要2秒。但是,当嵌入到较大的查询中时,总体执行时间会急剧增加到 4-5 分钟。
我已确保在相关表上定义了适当的索引,包括时态表
nd.tblReqMatSum
。请注意,tmp.##mytable
是一个没有索引的全局临时表,但它几乎总是很小。尽管如此,性能问题仍然存在。
这是有问题的查询:
declare @result int=0
IF NOT EXISTS (
SELECT 1
FROM tmp.##mytable t
INNER JOIN nd.tblReqMatSum rms ON t.matnr = rms.matnr
WHERE rms.isActive = 1
)
BEGIN
SET @result = 1;
END
这是执行计划:
你说“注意 tmp.##mytable 是一个没有索引的全局临时表,但它几乎总是很小。”但它仍然有 1000 行,并且一个简单的嵌套循环(每次扫描整个表)会读取 589796 * 1000 行。
在该临时表上放置索引。
CREATE CLUSTERED INDEX CS ON ##material268194 ([material number])
UPDATE STATISTICS ##material268194 WITH FULLSCAN;
如果可以的话,最好使该索引唯一。
两个连接列之间也存在类型不匹配。一个是
nvarchar
,另一个是varchar
。它们应该相同,否则您会得到隐式转换,这会影响基数估计,因此通常会影响计划形状。