业务 SQL 优化问题

2021-12-20 10:45:49 +08:00
 sockball07

原有业务上有一 SQL 大概是这样

UPDATE
    table
SET
    sort = sort + 1
WHERE
    # 一些固定条件
    xxxx = xxxx
AND
    sort >= ?

sort 为整形

问题在于现在业务是一组 sort (已升序排列)条件多次调用该 SQL ,由于表中数据有个几万,多次调用就会很慢,问是否有可能使用一条 SQL 完成这批更新

举例: 如原表中数据 sort 值为[0, 1, 2, 6],输入一组 sort 条件为[1, 2],则表中数据 sort 值更新为[0, 3, 4, 8]

3576 次点击
所在节点    MySQL
24 条回复
Fri
2021-12-20 20:41:20 +08:00
试试把 where 条件里的字段加上联合索引
siweipancc
2021-12-21 09:15:33 +08:00
套娃更新语句……作内存乐观锁更新吧
sockball07
2021-12-21 11:53:39 +08:00
#16 @zheng96 和我优化另外 2 个的思路很像(一个也是 UNION ALL 固定数据,一个也是使用多个临时变量)像是一个结合体 应该是可行的 (还是很像一种循环

要指出的一个错误是 你的 @b 在没有初始化的情况下始终为 NULL 而 NULL 不能与任何类型作比较 于是执行 IF(@b != t.id, @a := 0, 0)的时候永远会是 FALSE 的逻辑

另外要提醒的是 IF(@b != t.id, @a := 0, 0) 为 TRUE 的逻辑中是一个赋值表达式 最终返回为 NULL
zheng96
2021-12-21 12:20:53 +08:00
@sockball07 是的有错误,我昨天没发现出来是因为当前连接的 session 的用户变量已经被我赋过值了。

IF(@b != t.id, @a := 0, 0) 这个语句只是为了赋值,返回值没有意义

下面这个 sql 断掉 session 在连也没有问题的:
select t.id,max(t.final) from (
select t1.id,
t1.sort,
if( @b!= t1.id, @a := 0, 0),
if( @b!= t1.id, @b := t1.id, 0),
if(t1.sort + @a >= t1.val, @a := @a + 1, 0),
t1.sort + @a as final
from (
select sort_test.id,
sort_test.sort,
tmp.val
from sort_test join (select 1 as val union all select 2) tmp
order by sort_test.id, tmp.val) t1,(select @a:=0,@b:=-1) t2
) t
group by t.id ;

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/823263

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX