昨天拙文中讲述了用自增方式创建一千六百万大表的方案,这回讨论的是用笛卡儿积,实践证明这种方案更快.
2020年3月15日08点58分实验开始
创建仅有四千数据的tb_4thousand1表:
SQL> CREATE TABLE tb_4thousand1 2 ( 3 id NUMBER not null primary key, 4 name NVARCHAR2(60) not null, 5 salary int NOT NULL, 6 createtime TIMESTAMP (6) not null 7 ); 表已创建。 已用时间: 00: 00: 00.12
给这张表充值:
SQL> insert into tb_4thousand1 2 select rownum, 3 dbms_random.string('*',dbms_random.value(6,20)), 4 dbms_random.value(1000,50000), 5 sysdate 6 from dual 7 connect by level<=4000 8 order by dbms_random.random; 已创建4000行。 已用时间: 00: 00: 00.48
再创建一张同构的表tb_4thousand2
SQL> CREATE TABLE tb_4thousand2 2 ( 3 id NUMBER not null primary key, 4 name NVARCHAR2(60) not null, 5 salary int NOT NULL, 6 createtime TIMESTAMP (6) not null 7 ) 8 ; 表已创建。 已用时间: 00: 00: 00.01
给这张表充值:
SQL> insert into tb_4thousand2 2 select rownum, 3 dbms_random.string('*',dbms_random.value(6,20)), 4 dbms_random.value(1000,50000), 5 sysdate 6 from dual 7 connect by level<=4000 8 order by dbms_random.random; 已创建4000行。 已用时间: 00: 00: 00.18
然后看看tb_4thousand1和tb_4thousand2表的笛卡儿积有多少数据:
SQL> select count(*) from (select t1.* from tb_4thousand1 t1 cross join tb_4thousand2 t2); COUNT(*) ---------- 16000000 已用时间: 00: 00: 00.56
一千六百万,这就是我们想要的,下面开始建表:
SQL> create table tb_16million2 as select t1.* from tb_4thousand1 t1 cross join tb_4thousand2 t2; 表已创建。 已用时间: 00: 00: 21.52
至此,实验时间为2020年3月15日09点00分,也就是说我们用两分钟就创建了一张一千六百万大表!
当然,这张表的id字段需要规整一下:
SQL> update tb_16million2 set id=rownum where 1=1; 已更新16000000行。 已用时间: 00: 13: 06.69
短短的更新语句,跑出了13分钟,真是个漫长的等待!看来需要一条条设置数据的sql就是耗时的。
最后给tb_16million2表设上主键:
SQL> ALTER TABLE tb_16million2 ADD CONSTRAINT tb_16million2_pk PRIMARY KEY (id); 表已更改。 已用时间: 00: 00: 40.60
至此实验结束,时间为2020年3月15日09点17分,其中13分钟是放在update语句上了。
好了,我们又多了一种创建大表的选择,那就是利用笛卡儿积,两分钟建成一千六百万大表的速度确实可以让人兴奋一把。
下面是上文提到的所有sql:
CREATE TABLE tb_4thousand1 ( id NUMBER not null primary key, name NVARCHAR2(60) not null, salary int NOT NULL, createtime TIMESTAMP (6) not null ) insert into tb_4thousand1 select rownum, dbms_random.string('*',dbms_random.value(6,20)), dbms_random.value(1000,50000), sysdate from dual connect by level<=4000 order by dbms_random.random CREATE TABLE tb_4thousand2 ( id NUMBER not null primary key, name NVARCHAR2(60) not null, salary int NOT NULL, createtime TIMESTAMP (6) not null ) insert into tb_4thousand2 select rownum, dbms_random.string('*',dbms_random.value(6,20)), dbms_random.value(1000,50000), sysdate from dual connect by level<=4000 order by dbms_random.random select count(*) from (select t1.* from tb_4thousand1 t1 cross join tb_4thousand2 t2) create table tb_16million2 as select t1.* from tb_4thousand1 t1 cross join tb_4thousand2 t2 update tb_16million2 set id=rownum where 1=1; ALTER TABLE tb_16million2 ADD CONSTRAINT tb_16million2_pk PRIMARY KEY (id);
我的环境:
# | 类别 | 版本 |
1 | 操作系统 | Win10 |
2 | 数据库 | Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production |
3 | 硬件环境 | T440p |
4 | 内存 | 8G |
知识是需要大量实践的,成千上万条知识,通过实践才会深深刻画在脑海中,构成一个工程师真正的竞争力。
--2020年3月15日--