@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-sql的java驱动里性能最好。
|
把insert 语句注释掉, 看你的程序运行10次是否会正常
|
--> Error即是JVM的問題,大概是garbage collection太慢:roll:
試試每10000條作一次garbage collection 看看:roll:
--> 這句每一次作了3個物件,改一個看看
|
-->
但是配合3.0.16和3.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
|
用于退出IF,CASE,LOOP,REPEAT以及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、 参数不区分IN,OUT,全部为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执行update,insert,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则表示更新前的原值