在较大的查询中使用IF NOT EXISTES子查询时,我遇到了显著的性能差异.当独立运行时,子查询执行得很快,大约需要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

执行计划如下:

https://www.brentozar.com/pastetheplan/?id=B1sdm3YBp

enter image description here

enter image description here

enter image description here

推荐答案

你说

请注意,tmp.##mytable是一个没有索引的全局临时表,但它几乎总是非常小.

但它仍然有1,000行,一个简单的嵌套循环(每次扫描整个表)会读取589796*1,000行.

在那个临时表上建立一个索引.

CREATE CLUSTERED INDEX CS ON ##material268194 ([material number])

UPDATE STATISTICS ##material268194 WITH FULLSCAN;

如果可以的话,最好使这个索引是唯一的.

两个联接列之间的类型也不匹配.一个是nvarchar,另一个是varchar.它们应该是相同的,否则您会得到一个隐式转换,这会影响基数估计,因此通常会影响计划形状.

Sql相关问答推荐

使用group by后我的平均输出不是我想要的

为什么Postgrs Planner会在输出部分中显示我在查询中不使用的列?'""

删除MariaDB数据库中的JSON数据

为什么两个不同的窗口函数给出不同的排序结果?

对非RUST源代码字符串使用`stringify!`,例如SQL查询

使用SQL创建列出两个时间戳之间小时数的列

DBeaver将过程中的属性列表转换为字符串

SQL:如何在表中同时使用GROUPING和CONDITION?

在xml.Modify方法中使用子字符串和可能的替代方法

如何在连接中使用三个不同的列,从而在PostgreSQL中只获得两个列?

不存在记录的国外关键点

group-by-clause具有特定列,而不是oracle的toad中的all

在 PostgreSQL 中,如何让多个判断约束引用相同的值数组?

SQL 将 Varchar 转换为日期

每组使用平均值来填补缺失值的SQL

从 varchar 列中删除特殊字符后的前面的零和字符时遇到问题

存储过程 - 动态 SQL 中不同列值的计数

在 MySql 数据库中的两个日期之间搜索

使用 JSON_BUILD_OBJ 从 Postgres 返回 JSON

REGEXP 用于字符串格式化以对用空格分隔的字符和数字进行分组