oracle 是如何在 1 秒内进行 100 万次插入的

wor*_*cle 3 mysql sql database oracle postgresql

几年前发现oracle可以实现1秒100万次插入,先解释一下这个,我记得在SQL/PLUS交互命令行

set timing on
create table tbl as 
select ROWNUM c1, 
       dbms_random.string('x', 6) c2, 
       sysdate + ROWNUM / 24 / 3600 c3 
  from dual 
connect by level < 1000000
Run Code Online (Sandbox Code Playgroud)

上面的代码将创建一个包含 100 万条记录的表,SQL/PLUS 会给你经过的时间。那是在Windows XP(SP3)PC机上,供应商是Lenovo Think Centre,忘记型号了,硬件性能还不错。

但是我测试了 MySQL PostgreSQL 甚至 sqlite,因为我找不到一个语句来为它们生成数百万个结果,然后我做了一个循环,比如

declare i int default 0;
start transaction;
when i < 1000000
do
    insert into tbl values(i, rand(), now() + interval 1 second);
    set i = i + 1;
end when;
commit;
Run Code Online (Sandbox Code Playgroud)

不完全是这样,但需要几秒钟才能完成,每秒只产生 200~300K,基本相同的硬件,但在 Linux 上

我想知道oracle有什么机制,我确定重点是磁盘的IO,我知道oracle有这个表的一个段(因为没有索引),里面有很多扩展,然后是块,我认为它分配比减少分配频率,批量刷新,更好的内部结构需要更多,但我不确定,我不认为只有这种方式可以做出如此巨大的改进,此外我认为其他rdbms也有这种方式,但是为什么...

a_h*_*ame 5

您正在将苹果与橙子进行比较。在 Oracle 中,您正在基于批量插入的选择创建表。第二个代码示例是做百万单个插入它们总是方式比批量插入慢。

你也用 Postgres 标记了它,所以请在那里尝试以下操作:

create table tbl as 
select i as c1, 
       random() as c2, 
       clock_timestamp() + interval '1' second as c3 
  from generate_series(1,1000000) i
;
Run Code Online (Sandbox Code Playgroud)