explain實驗數據準備
Mysql-Explain(一):explain簡介和輸出列解釋
Mysql-Explain(二):explain實驗數據準備
Mysql-Explain(三):輸出列-id
Mysql-Explain(四):輸出列-select_type
Mysql-Explain(五):輸出列-type
Mysql-Explain(六):輸出列-possiable_keys、key、key_len
Mysql-Explain(七):輸出列-ref、rows
Mysql-Explain(八):輸出列-extra
上一篇博客簡單介紹了explain的作用,並且通過表格的形式羅列出了所有explain輸出列的相關信息。不過如果僅僅看文字可能還是難以理解其中的含義,更何況本人文筆羞澀,還可能會存在言不達意的情況,所以還是通過實驗來一一解讀較好。
實驗所需要的表格一共有三張:student、school、major,表結構如下
- stuednt:學生
- school:學校
- major:專業
通過sql腳本來創建表和插入實驗數據
-
Sql腳本執行之前先修改log_bin_trust_function_creators的值,這是因爲腳本包含函數和過程的創建。
mysql> show variables like "log_bin_trust_function_creators"; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | log_bin_trust_function_creators | OFF | +---------------------------------+-------+ 1 row in set, 1 warning (0.00 sec)
如果是OFF或者0,則需要通過下面的語句修改,等後面的sql腳本執行完後,可以再考慮修改回原來的值。
-- ----------- -- 0=OFF 1=ON -- ----------- set global log_bin_trust_function_creators = 1;
-
導入sql腳本
-- ---------------------------- -- 整個過程執行可能要幾分鐘的時間 -- ---------------------------- SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for major -- ---------------------------- DROP TABLE IF EXISTS `major`; CREATE TABLE `major` ( `id` int(11) NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for school -- ---------------------------- DROP TABLE IF EXISTS `school`; CREATE TABLE `school` ( `id` int(11) NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` int(11) NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `age` int(11) NULL DEFAULT NULL, `school_id` int(11) NULL DEFAULT NULL, `major_id` int(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Procedure structure for insert_majors -- ---------------------------- DROP PROCEDURE IF EXISTS `insert_majors`; delimiter ;; CREATE PROCEDURE `insert_majors`(num int) BEGIN DECLARE i INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT -1; END; START TRANSACTION; REPEAT SET i = i + 1; INSERT INTO major VALUES(i,CONCAT('專業',i)); UNTIL i = num END REPEAT; COMMIT; END ;; delimiter ; -- ---------------------------- -- Procedure structure for insert_schools -- ---------------------------- DROP PROCEDURE IF EXISTS `insert_schools`; delimiter ;; CREATE PROCEDURE `insert_schools`(num int) BEGIN DECLARE i INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT -1; END; START TRANSACTION; REPEAT SET i = i + 1; INSERT INTO school VALUES(i,CONCAT('學校',i)); UNTIL i = num END REPEAT; COMMIT; END ;; delimiter ; -- ---------------------------- -- Procedure structure for insert_students -- ---------------------------- DROP PROCEDURE IF EXISTS `insert_students`; delimiter ;; CREATE PROCEDURE `insert_students`(start int,num int) BEGIN DECLARE i INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT -1; END; START TRANSACTION; REPEAT set i = i + 1; insert into student values(start + i,rand_str(10),FLOOR(20 + RAND() * 10),FLOOR(RAND() * 1000),FLOOR(RAND() * 500)); UNTIL i = num END REPEAT; COMMIT; SELECT 1; END ;; delimiter ; DROP PROCEDURE IF EXISTS `insert_students2`; delimiter ;; CREATE PROCEDURE `insert_students2`(batch int,num int) BEGIN DECLARE i INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SELECT i; END; START TRANSACTION; REPEAT set i = i + 1; call insert_students((i-1) * num ,num); UNTIL i = batch END REPEAT; COMMIT; SELECT i; END ;; delimiter ; -- ---------------------------- -- Function structure for rand_str -- ---------------------------- DROP FUNCTION IF EXISTS `rand_str`; delimiter ;; CREATE FUNCTION `rand_str`(n int) RETURNS varchar(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci BEGIN DECLARE char_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; DECLARE return_str VARCHAR(255) DEFAULT ''; DECLARE i INT DEFAULT 0; WHILE i < n DO SET return_str = CONCAT(return_str,SUBSTRING(char_str,FLOOR(1+RAND() * 52),1)); SET i = i + 1; END WHILE; RETURN return_str; END ;; delimiter ; -- 如果要改變插入表的數據行數,可以修改這裏的參數 call insert_schools(1000); call insert_majors(500); -- 第一個參數分20批次插入,第二個參數每個批次插入100000,所以一共是200w條記錄 call insert_students2(20,100000); SET FOREIGN_KEY_CHECKS = 1;
檢查表和數據
- student:一共插入了200w行記錄,由於是實驗數據所以學生名稱是隨機生成的字符串
- school:一共插入1000行記錄
- major:一共插入500行記錄
三張表暫時都還不創建索引,這等到後續實驗的時候再陸續創建。
有了實驗的表和數據後,那就可以執行後面的實驗啦。