SQL Server Java 批量更新 VS 使用 join 批量插入和更新

问题描述 投票:0回答:1

我有一个案例,我需要更新一个非常大的表中的 10-50k 条目。桌子是这样的

int id PK
varchar username
boolean active
int category
and other random columns

有用户名和类别的索引。我必须更新类别 1 的 2 万条记录。我们可能还有 50 万条未触及的其他类别的记录。

我们在 jtds 驱动程序上使用 spring jdbc,仍然使用 SQL Server。问题是我们认为哪种方法会更快。

  1. 在用户名列表上循环批量更新:

update table set active = 1 where username = ? and category = 1

  1. 批量插入临时表,然后使用联接更新:

insert into #temp values ?

然后一大:

update table set active = 1 from #temp join table on #temp.username = table.username and category = 1

有什么猜测一般来说哪种方法会更快吗?我可以为我运行测试,但这适用于其他人,有些拥有更快的数据库,有些较慢,有些通过网络,有些更快。

谢谢!

java sql-server jdbc
1个回答
0
投票

如果您有一种有效的方法将所有用户名输入 SQL,我会采用该方法并立即更新所有内容。虽然单个更新语句的开销并不大,但在 20k 次更新的过程中,这些开销将会增加。另外,如果您一次执行一个操作,则该操作不是原子操作,如果中途失败,这可能会或可能不会成为问题。

您可以做的一个选择是将所有用户名作为 json (或 xml,甚至是分隔字符串)传递,然后解压值并更新用户名是解压值之一的行。就我个人而言,我会选择 JSON,因为它是最简洁且安全的,不会出现分隔符引起的问题。

以下是一些如何在 SQL 中实现这一目标的示例。所有这些都假设您格式化某种序列化的用户名字符串。

使用 JSON:

declare 
    @UsernamesJSON nvarchar(max) = N'[ "alice", "bob", "charlie" ]',
    @Category int = 1

update t
set Active = 1
from MyTable t
inner join openjson(@UsernamesJSON) s
    on t.Username = s.Value
where t.Category = @Category

使用分隔字符串

-- These are your input parameters from your app
declare 
    @Usernames nvarchar(max) = N'Alice|Bob|Charlie|Deborah|Eggbert',
    @Category int = 1

update t
set Active = 1
from MyTable t
inner join string_split(@UserNames, '|') s
    on t.Username = s.Value
where Category = @Category

使用XML

declare @UsernamesXML xml = N'
<names>
    <name>alice</name>
    <name>bob</name>
    <name>charlie</name>
</names>
'

update t
set Active = 1
from MyTable t
inner join @UsernamesXML.nodes('names/name') as a(c)
    on t.username = a.c.value('.', 'varchar(50)')
where Category = @Category
© www.soinside.com 2019 - 2024. All rights reserved.