SQL UPDATE WHERE IN(列表)还是单独更新每个?

标签 sql sql-server

我最近正在尽力寻找在 SQL 中运行某些查询的最佳方法,这些查询可能可以通过多种不同的方式完成。在我的研究中,我遇到了很多人对 WHERE IN 概念的厌恶,因为它的工作方式固有的低效率。

例如:WHERE Col IN (val1, val2, val3)

在我当前的项目中,我正在对大量数据进行更新,并且想知道以下哪一个更有效:(或者是否存在更好的选项)

UPDATE table1 SET somecolumn = 'someVal' WHERE ID IN (id1, id2, id3 ....);

在上面,ID 列表最多可以有 1.5k 个 ID。

VS

循环遍历代码中的所有 ID,并为每个 ID 运行以下语句:

UPDATE table1 SET somecolumn = 'someVal' WHERE ID = 'theID';

对我自己来说,前者工作得更好/更快似乎更合乎逻辑,因为需要运行的查询更少。也就是说,我并不是 100% 熟悉 SQL 的细节以及查询队列的工作原理。

我也不确定就表锁和其他一般性能而言哪个对数据库更友好。

一般信息(如果有帮助的话),我使用的是 Microsoft SQL Server 2014,主要开发语言是 C#。

非常感谢任何帮助。

编辑:

选项 3:

UPDATE table1 SET somecolumn = 'someVal' WHERE ID IN (SELECT ID FROM @definedTable);

在上面,@defineTable 是一个 SQL“用户定义表类型”,其中的数据以(在 C# 中)类型 SqlDbType.Structured 的形式传递到存储过程

人们在问 ID 是如何进来的: ID 位于 List<string> 中在代码中,并在发送到存储过程之前用于代码中的其他内容。目前,ID 作为只有一列(ID)的“用户定义表类型”进入存储过程。

我认为将它们放在表中可能比让代码连接一个巨大的字符串并将其作为变量(看起来像 id1, id2, id3, id4)吐到 SP 中更好。等等

最佳答案

我正在使用你的第三个选项,效果很好。

我的存储过程有一个 table-valued parameter 。另请参阅Use Table-Valued Parameters .

在该过程中有一条语句,没有循环,就像您所说的:

UPDATE table1 SET somecolumn = 'someVal' WHERE ID IN (SELECT ID FROM @definedTable);

最好调用该过程一次,而不是 1,500 次。一笔交易比 1,500 笔交易更好。

如果@defineTable中的行数超过10K,我会考虑将其分成10K的批处理。

<小时/>

您的第一个变体对于 IN 子句中的几个值来说是可以的,但是当您达到非常高的数字(60K+)时,您可以看到类似的内容,如 this answer 中所示。 :

Msg 8623, Level 16, State 1, Line 1 The query processor ran out of internal resources and could not produce a query plan. This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions. Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.

关于SQL UPDATE WHERE IN(列表)还是单独更新每个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33205087/

相关文章:

sql - TSQL - 字符更改为 INT

mysql - 将两个键连接/合并为一个键并删除重复项

sql-server - 更改主键名称

sql-server - 使用 LogParser 将 SharePoint 使用日志文件导出到数据库中

sql-server - 我如何在 sql 中找到我连接到的数据库名称

sql-server - 这些 sys.sp_* 存储过程在做什么?

php - 测试是否已经存在

java - 数据库多重内连接

sql - 多次从同一列获取 SQL 结果

SQL 选择前几行的条件