存儲過程: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 就是因為上面的值設置的太小
