在关于多行插入Oracle的discussion中,演示了两种方法:
第一:
insert into pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE)
select 8000,0,'Multi 8000',1 from dual
union all select 8001,0,'Multi 8001',1 from dual
第二
INSERT ALL
INTO t (col1, col2, col3) VALUES ('val1_1', 'val1_2', 'val1_3')
INTO t (col1, col2, col3) VALUES ('val2_1', 'val2_2', 'val2_3')
INTO t (col1, col2, col3) VALUES ('val3_1', 'val3_2', 'val3_3')
.
.
.
SELECT 1 FROM DUAL;
有人会争辩使用一个而不是另一个吗?
P.S。我自己没有做任何研究(甚至是解释计划),所以任何信息或意见都会受到赞赏。
感谢。
答案 0 :(得分:7)
从性能的角度来看,这些查询是相同的。
UNION ALL
不会影响效果,因为Oracle
仅在需要时才会估算UNION
'ed查询,它不会先缓存结果。
SELECT
语法更灵活,如果您想要更改某些内容,则可以更轻松地对SELECT
查询进行操作。
例如,此查询:
insert into pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE)
select 8000,0,'Multi 8000',1 from dual
union all select 8001,0,'Multi 8001',1 from dual
可以改写为
INSERT
INTO pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE)
SELECT 7999 + level, 0, 'Multi ' || 7999 + level, 1
FROM dual
CONNECT BY
level <= 2
通过用适当的数字替换2
,您可以获得任意数量的行。
如果是INSERT ALL
,则必须复制目标表格描述,如果需要,则表示40
行不可读。
答案 1 :(得分:4)
INSERT ALL
方法在向表中插入更多行时会出现问题。
我最近想在一个带有单个SQL语句的表中插入1130行。当我尝试使用INSERT ALL
方法执行此操作时,出现以下错误:
ORA-24335 - 不能支持超过1000列
当我使用INSERT INTO .. UNION ALL ..
方法时,一切都很顺利。
顺便说一下。在我发现这个讨论之前,我不知道UNION ALL方法:)
答案 2 :(得分:3)
我怀疑解决方案1是一个有效的黑客,可能效率低于Insert ALL的设计替代方案。
插入all实际上是为了您选择的结果,将多行插入到多个表中,例如:
Insert ALL
into
t1 (c1, c2) values (q1, q2)
t2 (x1, x2) values (q1, q3)
select q1, q2, q3 from t3
如果您想要加载数千行并且它们已经不在数据库中,我认为这不是最好的方法 - 如果您的数据在文件中,想要查看外部表或SQL Loader以有效地为您插入行。
答案 3 :(得分:3)
我尝试了一些测试,更快的解决方案应该是
insert into pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE)
select 8000,0,'Multi 8000',1 from dual
union all select 8001,0,'Multi 8001',1 from dual
在300℃至300℃之间缓冲。 400行(我尝试使用odbc,这个值可能取决于它的配置)
答案 4 :(得分:2)
利用UNION ALL
的语句在理论上具有很小的性能劣势,因为它必须在插入发生之前将所有语句的结果联合起来。
INSERT ALL
没有这个缺点,因为最终结果已经可以逐行处理。
但实际上Oracle内部的优化器应该可以忽略不计,这取决于您选择的偏好。
在我看来,INSERT ALL
是两者中人类可读的更好的,而UNION ALL
变体是在自动生成这样的插入时占用较少空间的变体。
答案 5 :(得分:-1)
如果您有大于1000的insert语句,则将所有insert语句放在.sql文件中,然后在Toad或SQL Developer中打开它,然后执行。将插入所有记录。
答案 6 :(得分:-2)
你应该考虑Array-Insert。
如果需要批量处理数百个插件,这是最小化网络流量的方法。