带有字符串连接的 SQL 很慢

Posted

技术标签:

【中文标题】带有字符串连接的 SQL 很慢【英文标题】:SQL with string concatenation is slow 【发布时间】:2021-10-12 03:09:21 【问题描述】:

我有一个需要 15 秒才能执行的存储过程。数据库是 SQL Server 2008 R2。

SQL查询如下,

SELECT * FROM EmployeeSetA
    UNION 
SELECT * FROM EmployeeSetB
WHERE
Name+''+Id NOT IN (SELECT Name+''+Id FROM EmployeeSetA) 

查询正在尝试联合 EmployeeSetA 和 EmployeeSetB,并确保在执行联合之前 EmployeeSetB 中的 Name 和 Id 不在 EmployeeSetA 中。

当我验证时,字符串连接导致 SQL 运行缓慢。有没有更好的方法?任何建议将不胜感激。

【问题讨论】:

更改为NOT EXISTS ( SELECT * FROM EmployeeSetA A WHERE A.Name = EmployeeSetB.Name AND A.Id = EmployeeSetB.Id ) 你确定是字符串连接吗? UNION 执行 DISTINCT,它通常执行 ORDER BY,这是一项昂贵的操作,尤其是在字符串上。 @Nick.McDermaid,在上面的 SQL 中,我没有看到 union 的缓慢性。我通过如下所示更改 SQL 得出的结论是字符串连接导致速度变慢, WHERE Name NOT IN (SELECT Name FROM EmployeeSetA) 当我删除字符串连接并仅使用一列进行验证时,它在 1 秒内执行。如果您有更好的方法/解决方案,请告知。 好的,您已经隔离了问题。我同意@Squirrel - 先试试他的解决方案。 @PhilCoulson,您能否举个例子说明如何做到这一点? 【参考方案1】:

您可以先将两张表堆叠起来,然后使用except 删除不需要的记录。如果这是您真正想要的,请随意将 union all 更改为 union。话虽如此,not exists 是理想的解决方案

select * from EmployeeSetA
union all
select * from EmployeeSetB
except 
select b.* from EmployeeSetB b
join EmployeeSetA a on a.name=b.name and a.id=b.id;

或者更直接,

select * from EmployeeSetA
union all
select b.* from EmployeeSetB b
left join EmployeeSetA a on a.name=b.name and a.id=b.id
where a.name is null or a.id is null;

【讨论】:

以上是关于带有字符串连接的 SQL 很慢的主要内容,如果未能解决你的问题,请参考以下文章

带有 sql 连接字符串的 perl 脚本看似故障转移点(。)

带有 JSP 的 JDBC 连接字符串 SQL Server 导致“非法转义字符”错误

带有数据目录的连接字符串(c#、sql server)

带有 Service Pack 2 的 SQL Server Developer Edition 的 jTDS 连接字符串

如何设置 SQL Server 连接字符串?

.NET / LINQ-SQL / ASP.NET 中的连接字符串地狱