Mysql-Explain(二):explain實驗數據準備

上一篇博客簡單介紹了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行記錄

三張表暫時都還不創建索引,這等到後續實驗的時候再陸續創建。

有了實驗的表和數據後,那就可以執行後面的實驗啦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章