如何将测试库里数据的表和数据复制到正式库里数据

EXP/IMP 导出生产库表的指定数据到测试库一例_数据库技术_Linux公社-Linux系统门户网站
你好,游客
EXP/IMP 导出生产库表的指定数据到测试库一例
来源:Linux社区&
作者:JingyuZhao
一般来讲,EXP/IMP是上一代导出导入程序,EXPDP/IMPDP是新一代的导出导入程序。对于大数据量的导出导入首选EXPDP/IMPDP,可以用到并行度,对表空间等操作上也更加的灵活。对于小数据量的迁移,可以使用exp/imp,操作更简单。
需求: exp 导出& A库(11.2.0.3)zjy用户的分区表t_jingyu_part部分数据,数据表空间 dbs_d_jingyu,索引表空间dbs_i_jingyu.
imp 导入& B库(11.2.0.4)test用户下,test用户的默认表空间dbs_d_test。
A库zjy用户下准备工作:
create tablespace dbs_d_jingyu datafile '+data' size 100Mcreate tablespace dbs_i_jingyu datafile '+data' size 20Mcreate user zjy identified by zjy default tablespace dbs_d_
create table t_jingyu_part(id number,deal_date date,area_code number,contents varchar2(4000))partition by range(deal_date)(partition p1 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p2 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p3 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p4 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p5 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p6 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p7 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p8 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p9 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p10 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p11 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p12 values less than(to_date('','YYYY-MM-DD')) tablespace dbs_d_jingyu,partition p_max values less than(maxvalue) tablespace dbs_d_jingyu );
insert into t_jingyu_part(id, deal_date, area_code, contents)select rownum, to_date(to_char(sysdate-365,'J')+trunc(dbms_random.value(0,365)),'J'), ceil(dbms_random.value(590,599)), rpad('*',400,'*') from dualconnect by rownum &= 100000;
create index idx_t_jingyu_part_id on t_jingyu_part(id, area_code) local tablespace dbs_i_
select count(1) from t_jingyu_part partition(P1); select count(1) from t_jingyu_part partition(P2);
select count(1) from t_jingyu_part where deal_date &= to_date('','yyyy-mm-dd') and deal_date &= to_date('','yyyy-mm-dd');
exp zjy/zjy parfile=exp.par
file=t_jingyu_part.dmplog=exp_t_jingyu_part.logtables=t_jingyu_partquery="where deal_date &= to_date('','yyyy-mm-dd') and deal_date &= to_date('','yyyy-mm-dd')"statistics=none
在可以使用直接路径导出的情景建议使用直接路径导出:direct=y 但在本例中不适用。
B库test用户:
create tablespace dbs_d_test datafile '+data' size 100Mcreate user test identified by test default tablespace dbs_d_
注:如果按需求,不在B库建立原表在A库时对应的表空间,就需要先在B库建立表,指定B库的表空间,比如dbs_d_然后再imp导入,否则必须先建立之前的表空间。
imp test/test file=t_jingyu_part.dmp log=imp_t_jingyu_part.log buffer=1024000 ignore=y full=y RESUMABLE=y
----------------------------华丽丽的分割线----------------------------
导入导出expdp IMPDP详解
Oracle 10g expdp导出报错ORA-4031的解决方法
Oracle 10gr2 rac expdp 报错UDE-00008 ORA-31626
Oracle中利用expdp/impdp备份数据库的使用说明
Oracle备份还原(expdp/impdp) &----------------------------Expdp/Impdp的相关参数----------------------------
更多Oracle相关信息见 专题页面
本文永久更新链接地址:
相关资讯 & & &
& (08/03/:02)
& (09/14/:09)
& (06月12日)
& (11/21/:01)
& (12/17/:36)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款在数据库测试中如何准备各种测试数据
免费下载: 或者 下载更多的 ,并加入 ,参与在线交流。引言在数据库开发和测试中,我们经常要准备很多各种各样的测试数据,如 del,asc 格式的,时间日期型的,二进制的,big endian 和 little endian 的,还有特殊的二进制格式 zoned 和 packed 的数据。本文介绍几个快速自动生成这些不同种类测试数据的方法。各种数据格式简介及特性在介绍如何生成数据之前,有必要了各种数据类型的格式及其特征。下面依次介绍这些数据格式的特性。定界 ASCII (DEL) 文件格式定界 ASCII (DEL) 文件是指带有行定界符和列定界符的顺序 ASCII 文件。每个 DEL 文件都是一个 ASCII 字符流,该字符流由先按行排序然后按列排序的单元值组成。数据流中的各行由行定界符分隔,在每一行中,各个单元值由列定界符分隔。以下是一个 DEL 文件示例。数据流中的行由行定界符回车换行符分隔,行中的列值由列定界符逗句分隔,其内容如下:清单 1:定界 del 文件格式示例"Smith, Bob",
"Jones, Bill",
"Williams, Sam",452,193.78非定界 ASCII (ASC) 文件格式非定界 ASCII 格式可以用于与任何使用列数据格式的 ASCII 产品(包括字处理器)交换数据。每个 ASC 文件都是 ASCII 字符流,该字符流由按行列排序的数据值组成。数据流中的各行由行定界符分隔。在一行中,每一列都由开始结束位置对定义。每个位置对都表示一行中以字节位置形式指定的位置。一行内的第一个位置为字节位置 1。每个位置对的第一个元素是该列的开始字节,每个位置对的第二个元素是该列的结束字节。各个列可以重叠。ASC 文件中的每一行的列定义相同。以下是一个 ASC 文件示例。每一行都以换行符序列结尾(在 Windows 操作系统上,每一行都以回车符 / 换行符序列结尾)。清单 2:非定界 asc 文件格式示例 Smith, Bob
Jones, Suzanne
Williams, Sam
193.78二进制文件格式理论上而言,binary 直接是原生态的二进制流,别人不知道类型根本打不开。但是 varchar 读写容易,而且可以通过加密的方式进行传输。大端(big endian)与小端(little endian)endian 翻译为“字节序”,又称端序,尾序。在计算机科学领域中,字节序是指存放多字节数据的字节(byte)的顺序,典型的情况是整数在内存中的存放方式和网络传输的传输顺序。Endianness 有时候也可以用指位序(bit)。一般而言,字节序指示了一个 UCS-2 字符的哪个字节存储在低地址。如果 LSByte 在 MSByte 的前面,即 LSB 为低地址,则该字节序是小端序;反之则是大端序。在网络编程中,字节序是一个必须被考虑的因素,因为不同的处理器体系可能采用不同的字节序。在多平台的代码编程中,字节序可能会导致难以察觉的 bug。BIG ENDIAN:最低位地址存放高位字节,可称高位优先,内存从最低地址开始按顺序存放(高数位数字先写)。最高位字节放最前面。LITTLE ENDIAN:最低位地址存放低位字节,可称低位优先,内存从最低地址开始按顺序存放(低数位数字先写)。最低位字节放最前面。示例如下:假设从地址 0x 开始的一个字中保存有数据 0x1234abcd, 那么在两种不同的内存顺序的机器上从字节的角度去看的话分别表示为 :1)
little endian: 在内存中的存放顺序是 0xxcd,0xxab,0xx34,0xx122)
endian: 在内存中的存放顺序是 0xx12,0xx34,0xxab,0xxcd区标十进制格式区标十进制(Zoned-decimal) 格式是指每个 byte 可以包含一个 digital 或者 character。 在 Zoned-decimal 格式中每个 byte 被分成两部分:一个 4 bit 的 zone 部分 和一个 4 bit 的 digit 部分。如果是正数则符号部分为 F(1111), 如果是负数则符号部分是 D(1101)。 如图 1 所示:图 1. 区标十进制格式根据上面所描述的区标十进制格式数据的特征,我们可以得知 21544 的区标十进制的十六进制如图 2 所示。图 2. 21544 的区标十进制格式的十六进制示例压缩十进制格式压缩十进制(packed-decimal)格式是指每个存储字节(除了低位字节外)有两个十进制数字。低位字节的左区有一个数字而在右区有一个符号(+或-),使用标准符号:正数是十六进制 F,负数是十六进制的 D。压缩十进制格式看来是这样的:低位字节的符号部分表明了在数字部分描述的数字值是正数还是负数。如图 3 所示。图 3. 压缩十进制格式根据上面的描述,我们可以得知 21544 的压缩十进制的十六进制如图 4 所示。图 4. 21544 的压缩十进制格式的十六进制示例不同格式的数据生成方法在介绍了各种数据类型之后,我们来介绍一下生成这些数据类型的方法定界 ASCII (DEL) 文件格式数据的生成方法我们在准备这一类型的测试数据时,通常考虑到的是,列定界符,行定界符,每一列的数据类型,数据文件的行数和列数。结合上一节介绍的定界文件格式数据的特征,我们用工具写脚本来生成此类型数据文件时,注意把定界符,行数,列数,每列数据类型等设为变量。由于 perl 上具有强大的正则表达式和模式匹配功能并且很灵活,这里我们选择 perl 为编程语言。由于篇幅有限,一些全局的输入变量的设置等这里就不详细介绍,详情请见代码下载部分。
这里仅以常见的 char 类型的数据为例来说明 perl 脚本怎么实现生成这类数据。
清单 3 的脚本生成字符类型的数据,变量 $CD 是指的 character delimiter,
默认是双引号。字符类型的包括:char,char(n),varchar(n),varying char(n) 等,
在生成这类数据的时候注意区分这些类型。另外一点,在下面的代码中第一个 if 中我们也对这样的情形做出了处理:
在方括号"[]"中指定生成字符串的范围,中间用空格分开。例如,
我们如果想要生成的 char(8) 的字符串在"hello","nihao","china"这些中随机选择。
可以在输入数据类型时这样表示:char(8)[hello nihao china]。详见清单 3。清单 3:生成字符类型的数据
# if the input type is char
if($LIST[$j]=~/char\((\d+)\)/i){
if($LIST[$j]=~/char\(\d+\)\[(.*)\]/i){
@chars = split(' ',$1);
$charsL = @
$VALUES[$j] = $chars[int(rand($charsL))];
$VALUES[$j] = $CD.$VALUES[$j].$CD;
}elsif($LIST[$j]=~/varchar\((\d+)\)/i){
$varL = int(rand($1))+1;
@char = (0..9,'$','%','a'..'z','A'..'Z','-','+','_');
$VALUES[$j] = join '', map{$char[int rand @char]}0..($varL-1);
$VALUES[$j] = $CD.$VALUES[$j].$CD;
}elsif($LIST[$j]=~/varying char\((\d+)\)/i){
$varL = int(rand($1))+1;
@char = (0..9,'$','%','a'..'z','A'..'Z','-','+','_');
$VALUES[$j] = join '', map{$char[int rand @char]}0..($varL-1);
$VALUES[$j] = $CD.$VALUES[$j].$CD;
$maxLen = $1;
@char = (0..9,'$','%','a'..'z','A'..'Z','-','+','_');
$VALUES[$j] = join '', map{$char[int rand @char]}0..($maxLen-1);
$VALUES[$j] = $CD.$VALUES[$j].$CD;
}对于我们常用的日期类型的数据生成函数时要注意的是:对于年:要考虑闰年和非闰年的区别,如果是闰年,2 月就有 29 天,非闰年 2 月只有 28 天。月份有三种表示方式:(1)、用 1 位数来表示:如 1 月到 9 月;(2)、用 2 位数来表示:即所有的月份都用两位数来表示: 01~12;(3)、用三位数来表示,如 Jan~Dec。日:类似于月,也有一位数的和两位数等等。根据测试需求选择不同的数据格式。如:如果需要生成格式为:YYYY-MM-D,那么输入生成数据类型时用:date[YYYY-MM-D]。同样对于 TIME,TIMESTAMP 也要做类似的处理。这三种类型表示方式有很多种,所以在处理这些类型时都要考虑到。由于篇幅有限,具体代码详见代码下载部分(genDataFile.pl)单独处理好各种数据类型后,再把生成所有类型的 del 格式的函数统一在一个脚本里,统一输入和输出参数。就这成了一个生成 del 数据类型的小工具了!运行该脚本,根据提示输入相关变量的值,并指定文件名的数据文件,如图 5 所示 :图 5. 生成 DEL 类型文件运行界面图 6 是上面脚本生成的数据文件,文件名为 a.del。图 6. 用工具 genDataFile.pl 生成的 DEL 数据文件内容示例非定界 ASCII (ASC) 文件格式数据的生成方法一般的 ASC 文件生成方式和 DEL 文件类型类似,只是可以不指定定位符,在对数据进行操作的时候会指定从第几列到第几列为输入的范围。zoned,packed,big endian 和 little endian 的类型的二进制文件比较特殊。下面分别介绍这几种类型的生成方法。大端(big endian)与小端(little endian)生成方法根据上面所描述的大端与小端数据的区别,我们可以这样设计函数随机产生不同类型的二进制数据文件:
先产生一个相应类型的随机数,然后把相应的二进制文件和十进制结果保存起来。
注意:(这里一定要把相应的十进制文件也保存起来,因为二进制文件我们是看不懂的,
只有保存了相应的十进制,测试时输入二进制数据之后,把输出的结果与你原来保存的十进制数据比较才能得知最终结果正确与否!)
我们用 c 语言来编程生成二进制数据,清单 4 的脚本是以常见的 real 数据类型为例,来随机生成和保存其二进制和十进制文件流。
清单 4.生成各种数据类型的二进制数据 /* 仅列出 realdata 函数用到的全局变量 */
float ft =0.0;
char itoc[100]={0};
FILE * fp = NULL;
/* 存储二进制文件 */
FILE * fp1= NULL; /* 存储对应的十进制数据文件 */
int numItems = 0;
int numItems1 = 0;
int sys=0;
void realdata()
ft=10*rand()/(float)(RAND_MAX/1;
sprintf(itoc,"%f ",ft);
for(n=0;n < (strlen(itoc));n++)
numItems1 = fputc(itoc[n],fp1);
if (numItems1 == EOF)
printf("File write failed: errno = %d\n", errno);
fclose(fp1);
numItems = fwrite( & ft,4,1,fp);
if (numItems == 0)
printf("File write failed: errno = %d\n", errno);
fclose(fp);
}用同样的方法可以产生各种其它的类型的二进制文件。把这些函数组合成一个总的文件,加以控制产生的数据文件的行数和列数。就是一个生成 endian 类型数据的完整小工具了!图 7 是生成各种数据类型的二进制文件示例结果图。图 7. 生成 little endian 类型的二进制文件读到这里,大家可能会觉得奇怪,不是要介绍大端数据和小端数据的生成方法么,怎么这里只提到了一种啊?而且没有说明是哪种。
嘿嘿,这里我们用了一个小技巧。我们在测试的时候通常会在不通的平台上测试,我们也有不同平台的机器帐号。
由于一般的 Linux 系统下默认的是 little endian,一般的 AIX 系统下默认的是 big endian。
因此,我们只要把这个小工具放在相应的平台上去编译并运行就可以得到相应的数据类型的文件了!(详见附件中:bin_for_numeric.c)
如上面图 7 就是在 linux 平台上编译后获得 liunx.out,并运行 liunx.out 的结果,得到的就是 little endian 的数据文件。区标十进制格式数据的生成方法根据上一节介绍的区标十进制格式数据的特征,如果我们要随机生成此类型数据,
最末一个字节的可能性就只有正负 0~9,即 f0~f9 和 d0~d9,在程序里用数组 @sign 表示。其余的 bit 位只有 f0~f9 十种值,
这里用数组 @char 来表示。清单 5 的脚本生成区标十进制格式的数据。相关总代码详见 ( 详见附件中:genDataFileAsc.pl)清单 5.生成区标十进制格式的数据 if($LIST[$j]=~/(?:decimal|dec)\((\d+)\,(\d+)\)/i)
$novel=$2; #$2 为 dec(n,m) 中的 m 值
@char = ('f0','f1','f2','f3','f4','f5','f6','f7','f8','f9');
@sign = ('f0','f1','f2','f3','f4','f5','f6','f7','f8','f9',
'd0','d1','d2','d3','d4','d5','d6','d7','d8','d9');
# 随机产生 decimal 数据的总长度位数减 1 的数值。
$mains = join '', map{$char[int rand @char]}0..($1)-2;
$sign_flag = join '', map{$sign[rand @sign]}0;
$VALUES[$j] = $mains.$sign_
# 把数据打印到文件中
print FILE_Result pack('H'.$1*2,$VALUES[$j]);
if ($VALUES[$j]=~/d/i) {$mark = -1} else{$mark = 1};
$VALUES[$j] =~ s/d//
$VALUES[$j] =~ s/f//
$VALUES[$j] = $mark*$VALUES[$j]*(10**((-1)*$novel));
print FILE_Utf "$VALUES[$j]\t";
}压缩十进制格式数据的生成方法根据上一节介绍的压缩十进制格式数据的特征,最后四个比特用来表示正负符号,用数组 @sign 表示。
以 4 个比特为单位,其余的所有每个 4 比特只有 0~9 十种选择值。这里需要注意的是如果要生成的数据位数为奇数个,
如数据 21544 为 5 位,就直接把数据位和符号位拼接即可;如果要生成的数据位数为偶数位,则在最高四个比特位补"0",
再拼接生成的数据位和符号位。清单 6 列出了生成压缩十进制格式的数据的相关代码。清单 6.生成区标十进制格式的数据 # $j-- 列数
要生成的 decimal 数据的长度,即为 dec(n,m) 中 n 值
if($LIST[$j]=~/(?:decimal|dec)\((\d+)\,(\d+)\)/i)
$novel=$2;
#$2 为 dec(n,m) 中的 m 值
@char = (0..9);
@sign = ('d','f'); # 正数 or 负数
$mains = join '', map{$char[int rand @char]}0..($1)-1; # 随机产生 decimal 数据的总长度位数的数值。
$sign_flag = join '', map{$sign[rand @sign]}0; # 随机选择正负符号
if ( $1%2 == 1) # 数据长度为奇数
$VALUES[$j] = $mains.$sign_
$length = $1+1;
# 数据长度为偶数
$VALUES[$j] = '0'.$mains.$sign_
$length = $1+2;
##out put data into files
print FILE_Result pack('H'.$length,$VALUES[$j]); # 把 $VALUES[$j] 打包成'H'.$length 的二进制结构
if ($VALUES[$j]=~/d/i) {$mark = -1} else{$mark = 1};# 确定所产生的文件的正负符号
$VALUES[$j] =~ s/d//
$VALUES[$j] =~ s/f//
$VALUES[$j] = $mark*$VALUES[$j]*(10**((-1)*$novel));
print FILE_Utf "$VALUES[$j]\t";
}结束语总之,本文为您提供了一些常用的测试数据类型的数据文件生成的方法,可以有效的提高测试效率。致谢非常感谢孙潘,詹炳林等对这篇文章相关的程序编码方面所给予的帮助。
下载资源 (data_code | 9K)相关主题
参考 对 packed 数据类型的描述。
参考 对 zoned 数据类型的描述。
参考 ,了解 DB2 的详细产品信息和相关技术等全面的内容。
通过 :在这里可以学到更多关于 Information Management 的知识。还可以找到技术文档、how-to 文章、培训、下载、产品信息等。随时关注 developerWorks
添加或订阅评论,请先或。
有新评论时提醒我
static.content.url=http://www.ibm.com/developerworks/js/artrating/SITE_ID=10Zone=Information ManagementArticleID=813927ArticleTitle=在数据库测试中如何准备各种测试数据publish-date=正式数据库和测试数据库差异问题
18:14:10 +08:00 · 1784 次点击
现在的问题是大家都在测试环境下做开发.
许多组员改了数据库结构可能没记下来或者忘记了,当代码上线正式环境后就会出现各种小问题,请问这个大家是怎么解决的?
有对比数据库差异的工具么?还是手工记录改过的结构?
8 回复 &| &直到
16:01:24 +08:00
& & 18:24:45 +08:00
toad 可以帮到你,但是你们的发版流程是有问题的,工具只能帮助你,但解决不了实际问题。
& & 18:31:10 +08:00
@ 请教一下正确的发版流程是怎样的呢?
& & 18:38:01 +08:00
我这边有两个方案,你可以试一下,看你觉得哪个合适?( 1 )一种是使用 Migration ,就是每次的数据库修改或增加或删除都是都脚本的。通过脚本来修改,而不是每个人使用 sql ,而这个脚本是代码的一部分,比如
PHP 的 一个框架 Laravel 的 Migration 。( 2 )第二种是我现在在用的,一个软件: MySQL Workbench ,这个软件会有一个 Model 的感念,这个 Model 就是类似于你的建库脚本,所有人维护这个 Model 文件,然后数据库使用“同步”功能,每次你点几个按钮,就可以看到这个 Model 与你的数据库的差异,然后执行。Workbench 这个文件进版本管理,缺点是通过文件的变化看不出来 SQL 的修改,但是好处就是他们的“同步”功能。你可以试试。
& & 18:42:31 +08:00
& & 19:08:18 +08:00
有对比数据库差异, 这个应该不是个好方案.业界上的解决方案是将数据库也进行版本化管理. 比如 ruby 的 rails 自带的 Active Record Migrations或者是 Java 中的 Flyway / Liquibase如果是 PHP, 可以考虑使用
Phinx (没用过...)
& & 19:12:40 +08:00
@ 谢谢,恰好用的就是 PHP ,有机会研究一下
& & 11:30:33 +08:00
@ 开发环境--测试环境--沙箱环境--灰度环境--线上
& & 16:01:24 +08:00
数据库做在虚拟机上, 打 snapshot, 定期(比如每天)revent...
& · & 3234 人在线 & 最高记录 3762 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.1 · 18ms · UTC 03:25 · PVG 11:25 · LAX 20:25 · JFK 23:25? Do have faith in what you're doing.继上篇文章《》发布后在博客园首页展示得到了挺多的阅读量,我这篇文章就是对上篇文章的千万级数据库表在高并发访问下如何进行测试访问
这篇文章的知识点如下:
1.如何自写几十行代码就能模拟测试高并发下访问千万级数据库表
2.比较高并发下(200次/秒,2000次/秒,10000次/秒)数据库的性能
3.比较千万级数据库在查询时加索引与不加索引的巨大差异(说实话,这个测试结果让我自己本人也很惊讶)
针对上篇文章插入的1000万条数据到数据库后,我们进行了高并发下测试(模拟教师输入姓名和密码在1秒内登录数据库),线程类代码如下
import java.sql.C
import java.sql.DriverM
import java.sql.ResultS
import java.sql.SQLE
import java.sql.S
public class ThreadToMysql extends Thread {
public String teacherN
public ThreadToMysql(String teacherName, String password) {//构造函数传入要查询登录的老师姓名和密码
this.teacherName=teacherN
this.password=
public void run() {
String url = "jdbc:mysql://127.0.0.1/teacher";
String name = "com.mysql.jdbc.Driver";
String user = "root";
String password = "123456";
Connection conn =
Class.forName(name);
conn = DriverManager.getConnection(url, user, password);//获取连接
conn.setAutoCommit(false);//关闭自动提交,不然conn.commit()运行到这句会报错
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
if (conn!=null) {
Long startTime=System.currentTimeMillis();//开始时间
String sql="select id from t_teacher where t_name='"+teacherName+"' and t_password='"+password+"'";//SQL语句
String id=
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);//获取结果集
if (rs.next()) {
id=rs.getString("id");
conn.commit();
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
Long end=System.currentTimeMillis();
System.out.println(currentThread().getName()+"
查询结果:"+id+"
开始时间:"+startTime+"
结束时间:"+end+"
用时:"+(end-startTime)+"ms");
System.out.println(currentThread().getName()+"数据库连接失败:");
&测试类代码如下:
public class TestThreadToMysql {
public static void main(String[] args) {
for (int i = 1; i &=2000; i++) {
String teacherName=String.valueOf(i);
new ThreadToMysql(teacherName, "123456").start();
&一.在没有加索引的情况下测试:
把数据库的最大连接数设置为250:
测试代码:
public class TestThreadToMysql {
public static void main(String[] args) {
for (int i = 1; i &=200; i++) {
String teacherName=String.valueOf(i);
new ThreadToMysql(teacherName, "123456").start();
&测试结果:
100多秒啊。。。我的天,这用户体验也没准了O(&_&)O哈哈~
二.加索引后再次进行高并发下测试:
数据库加索引SQL语句如下:这里我有一个疑问,上个星期我加索引等了半个小时我都没加完索引我就停止了,今天下午居然只用了551秒就加完了索引。。。搞不懂
clean下项目代码后再次运行(尽量经常clean下项目去掉缓存,不然结果会有出入):
看到这个结果有没有被惊呆啊?哈哈加了索引由100多秒提升到1~2毫秒,查询速度提示1万多倍,查询性能得到大幅度变态级提升~~~
没加索引之前我查询单个记录都要2秒多
用explain查看语句可以知道要扫描全表,性能当然大幅度下降
下面我们来挑战2000线程同时并发访问查询数据库。看看结果:
把数据库最大连接数设置为2500
测试代码改为2000
public class TestThreadToMysql {
public static void main(String[] args) {
for (int i = 1; i &=2000; i++) {
String teacherName=String.valueOf(i);
new ThreadToMysql(teacherName, "123456").start();
&结果截图:
性能没问题,平均几十毫秒,很满意
下面我们来挑战一下1万个线程同时高并发访问,大家可以先想想结果会怎么样,哈哈
设置数据库最大连接数12000
测试代码改为10000(再次提示。clean一下项目去掉缓存,这样结果更准确)
public class TestThreadToMysql {
public static void main(String[] args) {
for (int i = 1; i &=10000; i++) {
String teacherName=String.valueOf(i);
new ThreadToMysql(teacherName, "123456").start();
&结果如下(运行后发现电脑有点卡):
结果出现两种报错,1.连接请求被拒绝 2.连接失效 3.不过也有一部分成功连接上并且正确运行
然后我在数据库查看最大连接响应数:
可以看出来就算你的数据库设置为再高你的数据库服务器也响应不过来。。。。顶多响应5758个
&小小总结,1.可以自己测试高并发下挑战数据库性能,2. 对索引在查询性能上的强大有一个大概认识& 很适合初学者学习了解
阅读(...) 评论()

我要回帖

更多关于 库里生涯数据 的文章

 

随机推荐