存储过程:The stored procedure
结构
CREATE [DEFINER = { user | CURRENT_USER }] PROCEDURE stored_procedure_name ([proc_parameter[,...]]) [characteristic ...] routine_body
proc_parameter(参数列表): [ IN(输入参数) | OUT(输出参数) | INOUT(即可输入也可输出) ] param_name(参数名称) type(参数类型) characteristic(指定存储过程特性): COMMENT 'string'(注释信息) | LANGUAGE SQL(说明body部分由SQL语句组成,LANGUAGE可选值只有SQL) | [NOT] DETERMINISTIC(指明存储过程执行结果是否确定 默认值:NOT DETERMINISTIC) | { CONTAINS SQL(默认 说明子程序包含SQL语句,但是不包含写数据语句) | NO SQL(说明子程序不包含SQL语句) | READS SQL DATA(说明子程序包含读数据读数据语句) | MODIFIES SQL DATA(说明子程序包含写数据语句) }(指定子程序使用存储过程的限制) | SQL SECURITY { DEFINER(默认 只有定义者才能执行) | INVOKER(拥有权限的调用者才可以执行) }(指明谁有权限执行)
routine_body(SQL代码内容,可以使用BEGIN...END表示SQL代码的开始和结束): Valid SQL routine statement [begin_label:] BEGIN [statement_list] …… END [end_label]
例子

#无参数 create procedure myFist_proc() ## 创建存储过程 begin //.... end; show create procedure myFist_proc(); call myFist_proc(); #带有输出参数的存储过程 create procedure mySecond_proc(out sumStudent int ) begin select count(*) into sumStudent from score where grade>80; end; call mySecond_proc(@sumStudent); select @sumStudent; ##带有输入参数的存储过程 create procedure myThird_proc(in minScore int ,out sumStudent int)# 创建存储过程 begin select count(*) into new_table_name from old_table_name where grade>minScore;#从一个旧表中选取数据,然后把数据插入另一个新表中 end; call myThird_proc(90); #大于90的 select @sumStudent;
创建1000万数据的测试表(电脑问题非常慢)
#创建表 CREATE TABLE `big_data_test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(16) DEFAULT NULL, `age` int(11) DEFAULT NULL, `email` varchar(64) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`), KEY `name_age` (`email`,`age`) USING BTREE, KEY `email` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #创建存储过程,开始插入数据 CREATE PROCEDURE `insert_data_p`(IN num INT) BEGIN DECLARE n INT DEFAULT 1;#申明变量n WHILE n <= num DO #当n小于传入的参数时执行循环插入 INSERT INTO big_data_test(name,age,email)values(concat('alex',n),rand()*50,concat('alex',n,'@qq.com')); set n=n+1; end while; ENd; #调用存储过程,插入1000万条数据(总耗时:382.614 sec) CALL insert_data_p(10000000);
这个超快 MySQL快速生成100W条测试数据转载连接
CREATE TABLE `vote_record` ( `id` INT (11) NOT NULL AUTO_INCREMENT, `user_id` VARCHAR (20) NOT NULL, `vote_id` INT (11) NOT NULL, `group_id` INT (11) NOT NULL, `create_time` datetime NOT NULL, PRIMARY KEY (`id`), KEY `index_user_id` (`user_id`) USING HASH ) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; #内存表 CREATE TABLE `vote_record_memory` ( `id` INT (11) NOT NULL AUTO_INCREMENT, `user_id` VARCHAR (20) NOT NULL, `vote_id` INT (11) NOT NULL, `group_id` INT (11) NOT NULL, `create_time` datetime NOT NULL, PRIMARY KEY (`id`), KEY `index_id` (`user_id`) USING HASH ) ENGINE = MEMORY AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; #创建函数及存储过程 CREATE FUNCTION `rand_string`(n INT) RETURNS varchar(255) CHARSET latin1 BEGIN DECLARE chars_str varchar(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; DECLARE return_str varchar(255) DEFAULT '' ; DECLARE i INT DEFAULT 0; WHILE i < n DO SET return_str = concat(return_str,substring(chars_str , FLOOR(1 + RAND()*62 ),1)); SET i = i +1; END WHILE; RETURN return_str; END; CREATE PROCEDURE `add_vote_memory`(IN n int) BEGIN DECLARE i INT DEFAULT 1; WHILE (i <= n ) DO INSERT into vote_record_memory (user_id,vote_id,group_id,create_time ) VALUEs (rand_string(20),FLOOR(RAND() * 1000),FLOOR(RAND() * 100) ,now() ); set i=i+1; END WHILE; END; #插入内存表 CALL add_vote_memory(1000000) #插入普通表中 INSERT into vote_record SELECT * from vote_record_memory #php.ini改下内存 tmp_table_size=1G max_heap_table_size = 1G
或者动态设置
SET GLOBAL tmp_table_size=2147483648; (无效果?)
SET GLOBAL max_heap_table_size=2147483648;(无效果?)
或者:
set session tmp_table_size=1024*1024*1024; (查看:show variables like '%tmp_table%';)
set session max_heap_table_size=1024*1024*1024; (查看:show variables like '%max_heap%';)
tmp_table_size 控制内存临时表的最大值,超过限值后就往硬盘写,写的位置由变量 tmpdir 决定
max_heap_table_size 用户可以创建的内存表(memory table)的大小.这个值用来计算内存表的最大行数值。
查看:show variables like '%tmp%';
max_tmp_tables=32 #客户端可以同时保持打开的最大临时表数
ERROR 1114 (HY000): The table 'vote_record_memory' is full 就是因为上面的值设置的太小