点击这里给我发消息

我的ITblog我作主  关注→ 『伊波拉』→ 测试 SzDlinXie- ITblog     

·√· 本ITblog站点记录相关的软件技术文档、网络技术杂志、测试技术杂谈等技术文档的管理站点.联系方式:MSN:dowling@sunlike.cn QQ:94595885

统计

积分与排名

测试技术网站链接

最新评论

批量插入数据MYSQL

 

@echo off

cls

 

set CLASSPATH=..\api\jogre.jar

set CLASSPATH=%CLASSPATH%;.

set CLASSPATH=%CLASSPATH%;classes

set CLASSPATH=%CLASSPATH%;lib\dom4j.jar

 

java org.jogre.server.JogreServer

 

 

建表
[code]
create database con_test;
use con_test;
create table test(id int not null,txt varchar (70),primary key (id),index (id));
[/code]

就两个字段,id加索引。

java程序给表循环10万次插入纪录,id(循环次数) 和 内容(这条记录是第=xx)


InsertTestMysql.java

[code]
import java.lang.*;
import java.sql.*;

public class InsertTestMysql{
        public static void main(String [] args){   
                java.util.Date now_start = new java.util.Date();
                long start_time=now_start.getTime();
               
                int st = 100000;
                String str,info;

                String db="org.gjt.mm.mysql.Driver";
                String host="jdbc:mysql://192.168.1.35/test";
                String user="root";
                String passwd="root";
                Connection con=null;
               
   
                try{
                        Class.forName(db).newInstance();
                }
                catch(Exception e){
                        System.out.println("
加载驱动失败:"+db);
                }
       
                try{
                        con=DriverManager.getConnection(host,user,passwd);
                        con.setAutoCommit(false);//
关闭事务自动提交

                        for (int i=1;i<=st;i++){
         
                                                info = "
这条记录是第=";
                                                info = info.concat(java.lang.Integer.toString(i));
                  str = "insert into test (id,txt) values(?,?);";
                  PreparedStatement pstmt = con.prepareStatement(str);
                  pstmt.setInt(1,i);
                  pstmt.setString(2,info);
                  pstmt.executeUpdate();
                  }       
                  con.commit();//
语句执行完毕,提交本事务
                  con.close();
                }
              catch(Exception e) {
                  System.out.println(e);
                }

                java.util.Date now_end = new java.util.Date();
                long end_time=now_end.getTime();
                long use_time=end_time-start_time;

                System.out.println("<<---
本页生成耗时["+use_time+"]毫秒("+((double)use_time)/1000+")--->>");
                System.out.println("\n<<---
共插入记录"+st+"-->>");
        }
}
[/code]


在不同版本的jdbc下,表现不同。

jdbc 3.1.7, 12770,12778
插入这个数目时,程序退出,中文正常。
jdbc 3.1.12 12000
插入这个数目时,程序退出,中文正常。

均出现以下提示:
"Exception in thread "main" java.lang.OutOfMemoryError: Java heap space"
“Java
堆 空间 错误,可能是我机器内存不够。但用3.10系列jdbc就正常。

jdbc 3.0.16-ga 10
万记录正常,中文正常。
jdbc 3.0.10 10
万记录成功,但中文错误。

使用3.1系列jdbc,程序运行后,机器剩余物理内存很快就成了40xxKB了。

这个,也可能是jdbc3.1系列需要内存大,我机器内存不足。

明天再去同学的AMD64 512M RAM 机器测试。


 

jdbc 3.0.16-ga 唯一这个正常的,测试结果为:

[code]
D:\Program Files\test\db_test>java InsertTestMysql
<<---
本页生成耗时[98582]毫秒(98.582)--->>

<<---
共插入记录100000-->>
[/code]

 

前几天又测试了下,用开源的jdts jdbc 连接ms-sql server 2000  sp3 其他同上,测试结果惨不忍睹:

[code]
D:\dev\java\src\ts\Ms-Sql>java InsertTestMssql
<<---
本页生成耗时[1746681]毫秒(1746.681)--->>

<<---
共插入记录100000-->>
[/code]


因为MicorSoft官方的jdbc不支持手动提交,因此用开源jdts,反正官方测试报告说jdts性能在ms-sqljava驱动里性能最好。


 

insert 语句注释掉, 看你的程序运行10次是否会正常

 

-->
Error
即是JVM的問題,大概是garbage collection太慢:roll:

試試每10000條作一次garbage collection 看看:roll:

-->
這句每一次作了3個物件,改一個看看


 

-->

但是配合3.0.163.0.10 都没问题。


我也曾设置过,每执行1000次就提交一次,照样是用3.1的驱动出问题。还是1w2时候。

 

事务太长了,每插入一条就commit一次;偶插入过3千万条,没有问题的

 

昨天,用3.1.12驱动,在同学的AMD 64 + 512M RAM 上测试了,2W记录,使用java -Xmx64m -Xmx128m 参数运行,可以顺利通过。

10W记录,照样完蛋。机器消耗的总内存(物理+交换文件)达到1.4GB 后,因为空间不够,自动中止。

 

如果直接插入而不用事务机制呢?

 

-->

我每次测试,首先就是默认的自动提交(每语句),用3.1驱动还是出错。

当记录数目小到能正常完成时,自动提交耗时是一次事务的10倍时间(记录不太多时,大于1W,差距缩小到2~3倍)。

自动提交:
[code]
##
默认
D:\Program Files\test\db_test>java InsertTestMysql
<<---
本页生成耗时[43693]毫秒(43.693)--->>

<<---
共插入记录1000-->>
[/code]

一次事务:
[code]
##
控制COMMIT,一次性提交
D:\Program Files\test\db_test>java InsertTestMysql
<<---
本页生成耗时[3846]毫秒(3.846)--->>

<<---
共插入记录1000-->>
[/code]


 

没问题啊,。我们每天都通过java程序插入几十万条数据做测试,都可以的

 

//mysql自己的驱动程序,下面的测试程序插入100000条记录,结果是:
//<<---
本页生成耗时[82781]毫秒(82.781)--->>
//<<---
共插入记录100000-->>
import java.sql.*;

public class InsertTestMysql {
        public static void main(String[] args) {
                java.util.Date now_start = new java.util.Date();
                long start_time = now_start.getTime();

                int st = 100000;

                String db = "com.mysql.jdbc.Driver";
                String host = "jdbc:mysql://192.168.2.108/develop";
                String user = "whl";
                String passwd = "MVu9H370uG";
                Connection con = null;

                try {
                        Class.forName(db).newInstance();
                } catch (Exception e) {
                        System.out.println("
加载驱动失败:" + db);
                }

                try {
                        con = DriverManager.getConnection(host, user, passwd);
                        PreparedStatement pstmt = con.prepareStatement("insert into test (id,txt) values(?,?);");
                        for (int i = 1; i <= st; i++) {
                                pstmt.setInt(1, i);
                                pstmt.setString(2, "
这条记录是第=" + i);
                                pstmt.executeUpdate();
                        }
                        con.close();
                } catch (Exception e) {
                        System.out.println(e);
                }

                java.util.Date now_end = new java.util.Date();
                long end_time = now_end.getTime();
                long use_time = end_time - start_time;

                System.out.println("<<---
本页生成耗时[" + use_time + "]毫秒("
                                + ((double) use_time) / 1000 + "
)--->>");
                System.out.println("\n<<---
共插入记录" + st + "-->>");
        }
}

 

 

 

 

 

 

 

 

 

 

MySQL存储过程资料收集

 

A

声明

描述

CREATE PROCEDURE

建立一个存放在MySQL数据库的表格的存储过程。

CREATE FUNCTION

建立一个用户自定义的函数,尤其是返回数据的存储过程。

ALTER PROCEDURE

更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。.

ALTER FUNCTION

更改用CREATE FUNCTION 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。.

DROP PROCEDURE

MySQL的表格中删除一个或多个存储过程。

DROP FUNCTION

MySQL的表格中删除一个或多个存储函数。

SHOW CREATE PROCEDURE

返回使用CREATE PROCEDURE 建立的预先指定的存储过程的文本。这一声明是SQL:2003规范的一个MySQL扩展。

SHOW CREATE FUNCTION

返回使用CREATE  FUNCTION建立的预先指定的存储过程的文本。这一声明是SQL:2003规范的一个MySQL扩展。

SHOW PROCEDURE STATUS

返回一个预先指定的存储过程的特性,包括名称、类型、建立者、建立日期、以及更改日期。这一声明是SQL:2003规范的一个MySQL扩展。

SHOW FUNCTION STATUS

返回一个预先指定的存储函数的特性,包括名称、类型、建立者、建立日期、以及更改日期。这一声明是SQL:2003规范的一个MySQL扩展。

CALL

调用一个使用CREATE PROCEDURE建立的预先指定的存储过程。

BEGIN ... END

包含一组执行的多声明。

DECLARE

用于指定当地变量、环境、处理器,以及指针。

SET

用于更改当地和全局服务器变量的值。

SELECT ... INTO

用于存储显示变量的纵列。

OPEN

用于打开一个指针。

FETCH

使用特定指针来获得下一列。

CLOSE

用于关闭和打开指针。

IF

一个An if-then-else-end if 声明。

CASE ... WHEN

一个 case声明的结构

LOOP

一个简单的循环结构;可以使用LEAVE 语句来退出。

LEAVE

用于退出IFCASELOOPREPEAT以及WHILE 语句。

ITERATE

用于重新开始循环。

REPEAT

在结束时测试的循环。

WHILE

在开始时测试的循环。

RETURNS

返回一个存储过程的值。

MySQL 5.0支持存储过程语句。

 

.创建存储过程

1.基本语法:

create procedure sp_name()
begin
.........
end

2.参数传递

.调用存储过程

1.基本语法:call sp_name()
注意:存储过程名称后面必须加括号,哪怕该存储过程没有参数传递

.删除存储过程

1.基本语法:
drop procedure sp_name//
2.
注意事项
(1)
不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程

.区块,条件,循环

1.区块定义,常用
begin
......
end;
也可以给区块起别名,如:
lable:begin
...........
end lable;
可以用leave lable;跳出区块,执行区块以后的代码
2.
条件语句

if 条件 then
statement
else
statement
end if;


3.
循环语句
(1).while
循环

[label:] WHILE expression DO

statements

END WHILE [label] ;

 

(2).loop循环

[label:] LOOP

statements

END LOOP [label];

 

(3).repeat until循环

[label:] REPEAT

statements

UNTIL expression

END REPEAT [label] ;

 

.其他常用命令

1.show procedure status
显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过程名称,创建时间等
2.show create procedure sp_name

存储过程创建语法:

CREATE PROCEDURE procedure_name ([parameter[,...])

[LANGUAGE SQL]

[ [NOT] DETERMINISTIC ]

[{CONTAINS SQL|MODIFIES SQL DATA|READS SQL DATA|NO SQL}]

[SQL SECURITY {DEFINER|INVOKER} ]

[COMMENT comment_string]

procedure_statements


 
可用SHOW PROCEDURE STATUS SHOW CREATE PROCEDURE 来查看存储过程信息
另,系统表INFORMATION_SCHEMA.ROUTINES也包含了存储过程的一些信息
同样地,函数也可以使用同样方式查看(SHOW FUNCTION STATUS)


函数的创建
 

CREATE FUNCTION function_name (parameter[,...])

RETURNS datatype

[LANGUAGE SQL]

[ [NOT] DETERMINISTIC ]

[ {CONTAINS SQL | NO SQL | MODIFIES SQL DATA | READS SQL DATA} ]

[ SQL SECURITY {DEFINER|INVOKER} ]

[ COMMENT comment_string ]

语句体


函数与存储过程基本一样,其区别主要有:
1
、 要使用RETURNS指定返回类型
2
、 函数必须返回值,且在语句体中使用RETURN返回(注意:指定返回类型用RETURNS,返回值用RETURN)
3
、 参数不区分INOUT,全部为IN类形


:
CREATE FUNCTION cust_status(in_status CHAR(1))
    RETURNS VARCHAR(20)
BEGIN
    DECLARE long_status VARCHAR(20);
    IF in_status = 'O' THEN        SET long_status='Overdue';
    ELSEIF in_status = 'U' THEN    SET long_status='Up to date';
    ELSEIF in_status = 'N' THEN    SET long_status='New';
    END IF;
    RETURN(long_status);
END;
 
调用:
SELECT cust_status('O');
 
触发器
 

CREATE [DEFINER={user|CURRENT_USER}] TRIGGER trigger_name

{BEFORE|AFTER} {UPDATE|INSERT|DELETE}

ON table_name

FOR EACH ROW

trigger_statements


 
意义:当对表table_name执行updateinsert,delete操作之前(before)或之后(after)时触发语句trigger_statements操作

:
mysql> CREATE TRIGGER account_balance_au
 AFTER UPDATE ON account_balance FOR EACH ROW
BEGIN
  DECLARE dummy INT;
  IF NEW.balance<0 THEN
     SET NEW.balance=NULL;
  END IF;
END
 
上述触发器表示:当更新表account_balance之后,如果更新的值balance小于0,则将它改为NULL,
:如果为OLD.balance则表示更新前的原值

 

posted on 2008-10-10 17:46 szdlinxie 阅读(4548) 评论(1)  编辑 收藏 引用 所属分类: JAVA基础杂志电脑技术杂志数据库信息资料操作系统技术杂谈

评论

# re: 批量插入数据MYSQL 2008-10-25 16:41 金山词霸2008

真是一次艰难的测试过程啊。  回复  更多评论   

只有注册用户登录后才能发表评论。
点击这里给我发消息