带有字符串连接的 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 导致“非法转义字符”错误
带有 Service Pack 2 的 SQL Server Developer Edition 的 jTDS 连接字符串