• 查询优化_准备数据-保存50万条数据


    1.员工表插50W条,部门表插1W条

    1.1.建表

    CREATE TABLE `dept` (
     `id` INT(11) NOT NULL AUTO_INCREMENT,
     `deptName` VARCHAR(30) DEFAULT NULL,
     `address` VARCHAR(40) DEFAULT NULL,
     `ceo` INT NULL ,
     PRIMARY KEY (`id`)
    ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
     
    CREATE TABLE `emp` (
     `id` INT(11) NOT NULL AUTO_INCREMENT,
     `empno` INT NOT NULL ,
     `name` VARCHAR(20) DEFAULT NULL,
     `age` INT(3) DEFAULT NULL,
     `deptId` INT(11) DEFAULT NULL,
     PRIMARY KEY (`id`)
     #CONSTRAINT `fk_dept_id` FOREIGN KEY (`deptId`) REFERENCES `t_dept` (`id`)
    ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    1.2.设置参数:log_bin_trust_function_creators

    创建函数,假如报错:This function has none of DETERMINISTIC......
    # 由于开启过慢查询日志bin-log, 我们就必须为我们的function指定一个参数。
    #主从复制,主机会将写操作记录在bin-log日志中。从机读取bin-log日志,执行语句来同步数据。
    #如果使用函数来操作数据,会导致从机和主键操作时间不一致。所以,默认情况下,mysql不开启创建函数设置
    #查看mysql是否允许创建函数:
    show variables like 'log_bin_trust_function_creators';
    #命令开启:允许创建函数设置:
    set global log_bin_trust_function_creators=1; 
    # 不加global只是当前窗口有效。mysqld重启,上述参数又会消失。
    #永久方法: 
    linux下:/etc/my.cnf下my.cnf[mysqld]加上:log_bin_trust_function_creators=1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.3.创建函数,保证每条数据都不同

    随机产生字符串

    DELIMITER $$
    CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR(255)
    BEGIN    
    DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
    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()*52),1));  
    SET i = i + 1;
    END WHILE;
    RETURN return_str;
    END $$
     
    #假如要删除
    DELIMITER ;
    drop function rand_string;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    随机产生部门编号

    #用于随机产生多少到多少的编号
    DELIMITER $$
    CREATE FUNCTION  rand_num (from_num INT ,to_num INT) RETURNS INT(11)
    BEGIN   
    DECLARE i INT DEFAULT 0;  
    SET i = FLOOR(from_num +RAND()*(to_num - from_num+1))   ;
    RETURN i;  
    END$$ 
     
    #假如要删除
    DELIMITER ;
    drop function rand_num;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.4.创建存储过程

    创建往emp表中插入数据的存储过程

    DELIMITER $$
    CREATE PROCEDURE  insert_emp(  START INT ,  max_num INT )
    BEGIN  
    DECLARE i INT DEFAULT 0;   
     SET autocommit = 0;    #设置手动提交事务
     REPEAT  #循环
     SET i = i + 1;  #赋值
     INSERT INTO emp (empno, NAME ,age ,deptid ) VALUES ((START+i),rand_string(6),rand_num(30,50),rand_num(1,10000));  
     UNTIL i = max_num  
     END REPEAT;  
     COMMIT;  #提交事务
    END$$
     
    #删除
    DELIMITER ;
    drop PROCEDURE insert_emp;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    创建往dept表中插入数据的存储过程

    #执行存储过程,往dept表添加随机数据
    DELIMITER $$
    CREATE PROCEDURE `insert_dept`(  max_num INT )
    BEGIN  
    DECLARE i INT DEFAULT 0;   
     SET autocommit = 0;    
     REPEAT  
     SET i = i + 1;  
     INSERT INTO dept ( deptname,address,ceo ) VALUES (rand_string(8),rand_string(10),rand_num(1,500000));  
     UNTIL i = max_num  
     END REPEAT;  
     COMMIT; 
    END$$
     
    #删除
    DELIMITER ;
    drop PROCEDURE insert_dept;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    1.5.调用存储过程

    Dept

    #执行存储过程,往dept表添加1万条数据
    CALL insert_dept(10000); 
    
    • 1
    • 2

    Emp

    #执行存储过程,往emp表添加50万条数据
    CALL insert_emp(100000,500000);
    
    • 1
    • 2

    2.批量删除某个表上的所有索引

    2.1.建好的索引存在哪了?

    SHOW INDEX FROM t_emp ; 只能查看索引,但不能删除。
    Drop index idx_name on table_name;
    `information_schema`.`STATISTICS` 存储索引的表(元数据库,统计表),我们可以对表数据进行删除操作。
    
    • 1
    • 2
    • 3

    2.2.知识点

    1)删除某一个索引
    DROP INDEX idx_xxx ON emp
    2)查出该表有哪些索引,索引名-->集合
    SHOW INDEX FROM t_emp
    元数据:meta DATA  描述数据的数据
    SELECT index_name  FROM information_schema.STATISTICS WHERE table_name='t_emp' AND table_schema='mydb';
    AND index_name <>'PRIMARY' AND seq_in_index = 1
    3)如何循环集合
    CURSOR 游标
    FETCH xxx INTO xxx
    4)如何让mysql执行一个字符串
    PREPARE XXX  预编译语句
    EXECUTE
    5)如何执行存储过程
    CALL proc_drop_index ('mydb','t_emp');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.3.创建存储过程

    删除表上所有索引

    DELIMITER $$
    CREATE  PROCEDURE `proc_drop_index`(dbname VARCHAR(200),tablename VARCHAR(200))
    BEGIN
           DECLARE done INT DEFAULT 0;
           DECLARE ct INT DEFAULT 0;
           DECLARE _index VARCHAR(200) DEFAULT '';
           DECLARE _cur CURSOR FOR  SELECT   index_name   FROM information_schema.STATISTICS   WHERE table_schema=dbname AND table_name=tablename AND seq_in_index=1 AND    index_name <>'PRIMARY'  ;
    #每个游标必须使用不同的declare continue handler for not found set done=1来控制游标的结束
           DECLARE  CONTINUE HANDLER FOR NOT FOUND set done=2 ;      
    #若没有数据返回,程序继续,并将变量done设为2
            OPEN _cur;
            FETCH _cur INTO _index;
            WHILE  _index<>'' DO 
                   SET @str = CONCAT("drop index " , _index , " on " , tablename ); 
                   PREPARE sql_str FROM @str ;
                   EXECUTE  sql_str;
                   DEALLOCATE PREPARE sql_str;
                   SET _index=''; 
                   FETCH _cur INTO _index; 
            END WHILE;
       CLOSE _cur;
    END$$
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2.4.执行存储过程

    CALL proc_drop_index("mydb","emp");
    CALL proc_drop_index("mydb","dept");
    
    • 1
    • 2
  • 相关阅读:
    Angular 服务端渲染 Angular Universal 实例
    【RocketMQ】事务的实现原理
    UnityVR一体机报错:GL_OUT_OF_MEMORY,[EGL] Unable to acquire context
    如何设计高可用架构
    解决:将Ubuntu系统打包成ios镜像并制作U盘系统
    【HDFS】Hadoop-RPC:客户端侧通过Client.Connection#sendRpcRequest方法发送RPC序列化数据
    Maven setting.xml 配置
    论文阅读——Large Selective Kernel Network for Remote Sensing Object Detection
    大数据相关
    前端重新部署通知用户刷新
  • 原文地址:https://blog.csdn.net/daai5201314/article/details/126800999