序言

我们表中有很多数据,其中有一张表关联另一张表,其中有一张表的ID关联另一张的某个字段,但是我们仅仅将ID同步过来了,在此之前的数据都没有同步过来。所以需要一个刷数据的脚本。(ORACLE),我之前其实MYSQL用的多,ORACLE我知道的甚少,幸运的是我有CHATGPT。他可以直接帮我优化SQL。尽管如此,对于一名自诩高级的程序员,SQL优化是必修课,我必须掌握它。

刷数据

我们写了一个脚本,如下:

DECLARE
v_count number;
BEGIN
FOR rw IN(
select T2.ID as rid,T1.xxx,T1.xxx 
from xxx T1
             inner join xxxT2
ON
T1.ID = T2.xxx
WHERE T2.xxx= 0
) LOOP
UPDATE T2
SET XXX=RW.XXX,XXX=rw.XXXwhere rw.rid = id;
v_count := v_count + 1;
if mod(v_count, 1000) = 0 then
  commit;
end if;
END LOOP;
COMMIT;
END;

这样就可以把所有的数据都刷一遍了,利用数据绑定与循环,其实这样也可以造数据、删除数据,可以举一反三的。很NICE的。GET新技能,感谢给我指导的同事。

SQL优化

我本来是服务于一家 TO B的企业,平时给客户调优是必备的技能,像什么内存溢出,什么CPU飙升,什么数据库连接池都是没什么大问题的,只要日志给到位。但是对于SQL调优,我们可以直接丢给DBA,导致了我们缺乏SQL调优的机会,幸运的是,在新东家这里,我可以为所欲为的调试SQL,去观察SQL可以优化的点。我发现了有一个SQL竟然需要执行1MIN以上(尝试复盘,直接卡死,经过漫长的等待,查出来了。)。数据量25 W左右。

SQL大致是这样的。

select xxx,xxx
from
(select xxx from (select xxx from (select xxx from (select xxx from a))) group by xxx) group by xxx

之前的经验告诉我,600ms之上的sql完全可以被判定为慢查询。我着手去修复这个sql,花了很长时间,我将嵌套查询拆开之后执行,发现SQL快了很多,随后又使用了内关联发现快了一点,不是很确定,又查了大概20遍,确实快了一点,我询问了我的代理,

它的意思是因为inner join是匹配的查询,双方都匹配,换言之,条件多了,而 left join只是匹配一方的匹配,甚至是空的(no matching)。所以慢。
后面我注意到又很多的group by,还有很多聚合操作,我将无用的group by全部干掉,减少无用的聚合(eg,sum)运算,然后 where 多加了几个条件,去查,发现查询时间是


1s 300ms 我很满意,其实可以更快的,但是我没有再深入了,因为第一时间不允许,第二层次不够,必须要以后经常和SQL打交道,才能更大限度的吸取sql调优经验。

结束语

在我们工作中,其实有很多地方值得思考,值得去看一看,哪怕只是根据你已有的知识,只要有心就行,过程中少不了同事的配合,再次感谢各位同仁!

更多推荐

记一次 SQL刷数据脚本 和 SQL调优