项目场景:
背景:使用数据库为人大金仓数据库,更新的数量大致为一百万,所有表均有索引
现有两张表,A表和B表。A表结构如下:
ID | ITEM_NUM | VALUE |
---|---|---|
123 | 83456234 | 螺母 |
456 | 14522457 | 潜艇 |
B表结构如下
ID | ITEM_NUM | VALUE |
---|---|---|
888 | 83456234 | 螺母 |
999 | 14522457 | 潜艇 |
需求如下:
需将B表的BIZID字段值更新为A表对应的ITEM_NUM的ID值,B表修改后结果如下:
ID | ITEM_NUM | VALUE |
---|---|---|
888 | 123 | 螺母 |
999 | 456 | 潜艇 |
问题描述
写了一条更新SQL:
UPDATE B SET B.BIZID = (SELECT ID FROM A WHERE A.ITEM_NUM = B.ITEM_NUM )
出现的问题:
- 执行太慢了,时间过长后会显示失败或者是数据库连接断了或者是锁表等各种原因会导致失败。
原因分析:
第一个原因可能是数据库中的未优化的查询语句,导致更新操作需要更多的计算成本才能完成,因此更新速度变慢。
更新速度慢也可能是由于数据库存储结构存在问题,在重复性操作较多的情况下,如果没有准确索引,数据库在处理更新时就需要频繁地扫描表,大大降低了更新速度。(本文的场景中都加了有效索引,所以排除该情况)
解决方案:
将数据进行分组后放到人大金仓服务器上执行
-
ksql连接人大金仓命令:./ksql -U 用户名 -p 端口号 -d 数据库名 -W 密码
-
将SQL转化为单条执行,放到服务器上面跑(后面加 \gexec 在服务器中才能跑,'a'||'b' 等价于'ab' )
SELECT 'UPDATE A SET A.BIZID='||A.ID||' WHERE A.BIZID='||B.BIZID||';' FROM A , B WHERE A.BIZID =B.ITEM_NUM AND A.ID %10 = 0 \gexec
SELECT 'UPDATE A SET A.BIZID='||A.ID||' WHERE A.BIZID='||B.BIZID||';' FROM A , B WHERE A.BIZID =B.ITEM_NUM AND A.ID %10 = 1 \gexec
SELECT 'UPDATE A SET A.BIZID='||A.ID||' WHERE A.BIZID='||B.BIZID||';' FROM A , B WHERE A.BIZID =B.ITEM_NUM AND A.ID %10 = 2 \gexec
.
.
.
.
SELECT 'UPDATE A SET A.BIZID='||A.ID||' WHERE A.BIZID='||B.BIZID||';' FROM A , B WHERE A.BIZID =B.ITEM_NUM AND A.ID %10 = 9 \gexec
3、成功后服务器将显示
UPDATE 1;
UPDATE 1;
UPDATE 1;
...