INSERT INTO table3
SELECT
tbl1.pk_1, tbl1.pk_2, tbl2.pk_3, tbl1.pk4
FROM
table1 tbl1, table2 tbl2
WHERE
tbl1.pk_1 = 'root' and
NOT EXISTS
(SELECT 1 FROM table3 tbl3
WHERE tbl3.pk_1 = tbl1.pk_1 and tbl3.pk_2 = tbl1.pk_2 and tbl3.pk_3 = tbl2.pk_3 and tbl3.pk_4 = tbl1.pk_4)
;
我的SQL语句看起来像这样。表1和表3有超过1000000行,表2有100行。这个SQL语句非常慢。全程耗时超过100秒。有什么办法可以改进吗?
使用MERGE,速度更快
merge into table3 tbl3
using (select tbl1.pk_1, tbl1.pk_2, tbl2.pk_3, tbl1.pk4
from table1 tbl1, table2 tbl2
where tbl1.pk_1 = 'root') tb1
on (tbl3.pk_1 = tbl.pk_1 and tbl3.pk_2 = tbl.pk_2 and tbl3.pk_3 = tbl.pk_3 and tbl.pk_4 = tbl1.pk_4)
when not matched then
insert (tbl3.pk_1, tbl3.pk_2, tbl3.pk_3, tbl3.pk_4)
VALUES (tbl.pk_1, tbl.pk_2, tbl.pk_3, tbl.pk_4);
我发现提高这个SQL语句的性能是非常困难的。我测试了MERGE,但是它需要200多秒。即使性能可以提高,我想也只能提高1到2秒,这并不能满足我们的业务需求。(我有大约20个这样的SQL语句)。所以我检查了我们的业务逻辑,发现这个SQL语句是不必要的。我们只需要一个更仔细的算法来收集新数据,做一个笛卡尔积,然后将这个新数据插入到表3中。通过这种方式,可以删除此SQL语句。新的过程只需要几秒钟!我认为当我们改进一个SQL语句时,请首先确保这个SQL语句是绝对必要的。
我很确定你的表表达式是不完整的:
FROM
table1 tbl1, table2 tbl2
您(可能不小心)在表1和表2之间生成了一个笛卡尔积,内存中有1000000 x 100条记录。您的表表达式可能应该是:
FROM
table1 tbl1, table2 tbl2
WHERE
tbl1.some_column = tbl2.some_column
或者更好(为了防止将来发生这样的事情)
FROM
table1 tbl1
JOIN
table2 tbl2 ON tbl1.some_column = tbl2.some_column