1、动态SQL
for i in 1.. 100000
loop
execute immediate 'INSERT INTO T VALUES('||i||')';
commit;
end loop;
end;
SQL被解析多次
2、绑定变量
for i in 1.. 100000 loop
execute immediate 'INSERT INTO T VALUES (:1)' using i;
commit;
end loop;
end;
使用绑定变量,SQL只解析一次
3、批量COMMIT
for i in 1.. 100000
loop
execute immediate 'insert into t values(:1)' using i;
end loop;
commit;
COMMIT时,必须等到redo写至磁盘,这样就会导致等待,这种等待称为日志文件同步(log file sync),使用批量COMMIT,可以减少等待时间
4、静态SQL
for i in 1.. 100000 loop
insert into t values(i);
end loop;
commit;
静态SQL是前置编译绑定,动态SQL是后期执行时才编译绑定
动态SQL适用于表名及查询字段名未知的情况。使用动态SQL(字符串拼接方式)会增加硬解析的开销
5、集合写法
Insertinto t select rownum from dual connect by level <=100000;
只解析、执行一次
6、直接路径插入
Insert/*+append*/ into tselect rownum from dual connect by level <=100000;
Commit;
直接路径插入是PGA直接向文件写数据,绕过SGA,所以基本不产生redo(产生redo的数据字典的变动)
在正式环境下,要想用到insert append带来的好处,一定要表打到nologging;完成操作后,需要把表设置为logging, alter table t logging; select s.logging from user_tables s where s.table_name='T'可以查看表的logging设置。
nologging 降低redo只是在部分场景下有效:
a.创建索引和重建索引
b.通过append,使用直接路径批量insert操作或SQL*load 直接路径加载数据
c.CTAS方式创建数据表s
d.大对象(LOB)的操作
e.一些alter table move/split
7、并行
Create table t parallel 2 as select rownum x from dual connect by level <=100000;