要求一需要1千万以上的stud记录并有各种各样的要求,那么就需要先编造这一千万条数据,上次做的时候用了常用姓 X 常用字 X 常用字的笛卡儿积,那么就出了一个问题,常用字的数据集合是3000,那么名部分的 3000 X 3000 = 0.9kw,我们一共需要1kw数据,而第一个名字就占了0.9kw,这样明显不太行,所以我们需要另一个合理的编造数据方法
--先建立学生表用于导入数据 droptable student_J314; createtable student_J314( sno char(10) primary key, namevarchar(10), sex varchar(2), tel varchar(20), e_mail varchar(20), birthday date ); set TIMING on; --康康等下的运行花了多少时间
--导入数据 droptable first_name; createtable first_name( fname varchar(5) ); droptable second_name; createtable second_name( sname varchar(5) ); droptablename; createtablename( namevarchar(10) ); --由于数据源在excel里,我们需要先导出来,求不出错一个一个来 --first_name loaddata infile'd:\blog\first.csv' append intotable first_name fieldsterminatedby',' trailing nullcols(fname) > sqlldr userid = U_J314/YcYyj1234 control = d:\blog\load.ctl --415条记录 --second_name loaddata infile'd:\blog\second.csv' append intotable second_name fieldsterminatedby',' trailing nullcols(sname) > sqlldr userid = U_J314/YcYyj1234 control = d:\blog\second.ctl --3177条记录 --姓和名都有了现在就需要来随机组合成名字了(编数据都要编得这么麻烦,没法吐槽了) --我创建一个生成随机名字的过程,为了防止出现某个姓的名字过多,这次我就用111 * 111 * 999的方法生成不少于一千万条数据(实际上我是生成了11111111条数据) dropprocedure P_name_J314; createorreplaceprocedure P_name_J314 is cnt PLS_INTEGER:=1; first varchar(5); second varchar(5); third varchar(5); maxl PLS_INTEGER:=11111111; begin FOR a in (select * from first_name whererownum<=100) loopexitwhen cnt > maxl; first:=a.fname; FOR b in (select * from second_name whererownum<=101) loopexitwhen cnt > maxl; second:=b.sname; FOR c in (select * from second_name whererownum<=1001) loopexitwhen cnt > maxl; third := c.sname; insertintonamevalues (first||second||third); cnt := cnt + 1; ENDLOOP; ENDLOOP; ENDLOOP; END; . /
--现在我们来建立插入数据的过程 dropprocedure P_student_J314; createorreplaceprocedure P_student_J314 is cnt PLS_INTEGER:=1; msno varchar(10); mname varchar(10); msex varchar(2); mtel varchar(20); me_mail varchar(20); mbirthday date; rsex PLS_INTEGER; rdate PLS_INTEGER; maxl PLS_INTEGER:=10001111; dif PLS_INTEGER; cursor c_name is (selectnamefromname); begin dif := ROUND(TO_NUMBER(to_date('19990731', 'YYYYMMDD') - to_date('19940101', 'YYYYMMDD'))); OPEN c_name; for ab in 1..80 LOOP EXIT WHEN cnt > maxl; for cd in 1..90 LOOP EXIT WHEN cnt > maxl; for ef in 1..50 LOOP EXIT WHEN cnt > maxl; for gh in 1..32 LOOP EXIT WHEN cnt > maxl; FETCH c_name INTO mname; rsex := DBMS_RANDOM.VALUE(1,1000); --随机性别,并把比例分好 if rsex <= 496 then msex := '男'; elsif rsex <= 993 then msex := '女'; else msex := '无'; endif; rdate := DBMS_RANDOM.VALUE(0,dif); --通过时间差来随机日期 mbirthday := to_date('19940101', 'YYYYMMDD') + rdate; insertinto student_J314 values(TO_CHAR(ab,'FM09')||TO_CHAR(cd,'FM09')||'17'||TO_CHAR(ef,'FM09')||TO_CHAR(gh,'FM09'), mname, msex, '123456', '321654', mbirthday); cnt := cnt + 1; ENDLOOP; ENDLOOP; ENDLOOP; ENDLOOP; END; . /
--然后,我们先查看数据文件的大小,这一句是查看数据文件路径 select file_name , tablespace_name from dba_data_files;
--下一步就是插入 exec P_student_J314;
--时间空间变化如下
2 要求有主键与没主键生成记录的时间比较
那就是再插入一次没主键的咯,有主键要判断主键约束,所以按道理来说没主键会快一些
下面是结果,果然是没主键快一些
3 要求建立基于sname的索引,并比较建立前后
既然要比较建立索引的前后,所以我先把建立前的时间长度做好
1 2 3 4 5 6 7 8 9 10
select * from student_J314 where sno='0302170101'; --可以看到这个人叫云夫步 selectcount(*) from student_J314 wherename='云夫步'; selectcount(*) from student_J314 wherenamelike'云%'; selectcount(*) from student_J314 wherenamelike'云夫%';
createindex index_name on student_J314(name); selectcount(*) from student_J314 wherename='云夫步'; selectcount(*) from student_J314 wherenamelike'云%'; selectcount(*) from student_J314 wherenamelike'云夫%'; --运行过程及时间如下,显然建立索引后速度快得多