SQL 批量插入
1、建库建表
CREATE TABLE dept(
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
dname VARCHAR(20) NOT NULL DEFAULT "",
loc VARCHAR(13) NOT NULL DEFAULT ""
)ENGINE=INNODB DEFAULT CHARSET=GBK;
CREATE TABLE emp(
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
empno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*编号*/
ename VARCHAR(20) NOT NULL DEFAULT "",/*名字*/
job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/
mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上级编号*/
hiredate DATE NOT NULL,/*入职时间*/
sal DECIMAL(7,2) NOT NULL,/* 薪水*/
comm DECIMAL(7,2) NOT NULL,/*红利*/
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部门编号*/
)ENGINE=INNODB DEFAULT CHARSET=GBK;
2、设置参数
创建函数,假如报错: This function has none of DETERMINIST..., 由于开启过慢查询日志,因为我们开启了 bin-log,我们就必须为我们的 function 指定一个参数。
但是这样设置会导致的问题是:如果 MySQL 重启,上述参数又会丢失,所以到达到永久配置的效果,需要修改配置文件,在 /etc/my.cnf[mysqld]
下加上 global log_bin_trust_function_creators=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 $$
CREATE FUNCTION rand_num( ) RETURNS INT(5)
BEGIN
DECLARE i INT DEFAULT 0;
SET i = FLOOR(100 + RAND()*10);
RETURN i;
END $$
4、创建存储过程
向 emp 表存储数据的存储过程
/* 建立存储过程(插入数据emp)*/
DELIMITER $$
CREATE PROCEDURE insert_emp(IN START INT(10) ,IN max_num INT(10) )
BEGIN
DECLARE i INT DEFAULT 0;
#set autocommit =0把autocommit设置成0
SET autocommit = 0;
REPEAT
SET i = i + 1;
INSERT INTO emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) VALUES ((START+i), rand_string(6) , 'SALESMAN', 0001, CURDATE(), 2000, 400, rand_num());
UNTIL i = max_num
END REPEAT;
COMMIT;
END $$
向 dept 表存储数据的存储过程
/* 向dept表存储数据的存储过程 */
DELIMITER $$
CREATE PROCEDURE insert_dept(IN START INT(10),IN max_num INT(10))
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit = 0;
REPEAT
SET i = i+ 1;
INSERT INTO dept(deptno, dname, loc) VALUES ((START+i) ,rand_string(10), rand_string(8));
UNTIL i = max_num
END REPEAT;
COMMIT;
END $$
5、调用存储过程
由于定义函数的时候是以 $$
这个符号作为结束符,现在要更换为普通语句:
DELIMITER;
下面开始调用:
CALL insert_dept(100, 10);
试试向 emp 表添加 50 万条数据:
CALL insert_emp(100001, 500000);
哈哈,虚拟机还可以,OK 妥妥的 50 万条数据!
Show profiles
1、Show profiles 是什么
Show profiles 是什么:是 mysql 提供可以用来分析当前会话中语句执行的资源消耗情况,可以用于 SQL 的调优测量
这就好比去超市买东西,买什么东西花了多少钱都是有明确的记录的,Show profiles 也是一样,记录 SQL 执行步骤耗时,每一步都做了记录。默认情况下,参数处于关闭状态,并保存最近 15 次的运行结果
2、Show profiles 分析步骤
① 查看当前版本是否支持
② 开启功能,默认是关闭,使用前需要开启
show variables like 'profiling%'
把之前的测试数据放过来
create table tbl_dept(
id int(11) not NULL auto_increment,
deptName varchar(30) default NULL,
locAdd varchar(40) default NULL,
primary key (id)
)engine=INNODB auto_increment=1 default charset=utf8;
create table tbl_emp(
id int(11) not null auto_increment,
name varchar(20) default null,
deptId int(11) default null,
primary key (id),
key fk_dept_id(deptId)
#constraint fk_dept_id foregin key('deptId') references tbl_dept(id)
)engine=innodb auto_increment=1 default charset=utf8;
insert into tbl_dept(deptName, locAdd) values ('RD', 11);
insert into tbl_dept(deptName, locAdd) values ('HR', 12);
insert into tbl_dept(deptName, locAdd) values ('MK', 13);
insert into tbl_dept(deptName, locAdd) values ('MIS', 14);
insert into tbl_dept(deptName, locAdd) values ('FD', 15);
insert into tbl_emp(name, deptId) VALUES ('z3', 1);
insert into tbl_emp(name, deptId) VALUES ('z4', 1);
insert into tbl_emp(name, deptId) VALUES ('z5', 1);
insert into tbl_emp(name, deptId) VALUES ('z3', 1);
insert into tbl_emp(name, deptId) VALUES ('w5', 2);
insert into tbl_emp(name, deptId) VALUES ('w6', 2);
insert into tbl_emp(name, deptId) values ('s7', 3);
insert into tbl_emp(name, deptId) values ('s8', 4);
insert into tbl_emp(name, deptId) values ('s9', 51);
然后开启 Show profile,进行了几条查询再 show profile
下面开始选取一条开始分析。
3、分析执行过程
现在假设分析的是语句 3 ,也就是 select * from tbl_dept:
从上面可以看出,通过 show profile 的分析,完整的呈现了一条 SQL 执行的全流程,配合着 MySQL 架构模型,其实很容易看出,先进行权限检查,打开表,初始化,优化器优化等等一系列的执行流程...
只能查看 CPU 和 IO 吗?当然不是,下面给出了常用的查询字段:
①ALL:显示所有的开销信息。
②BLOCK IO:显示块 IO 开销。
③CONTEXT SWITCHES:上下文切换开销。
④CPU:显示 CPU 开销信息。
⑤IPC:显示发送和接收开销信息。
⑥MEMORY:显示内存开销信息。
⑦PAGE FAULTS:显示页面错误开销信息。
⑧SOURCE:显示和 Source_function,Source_file,Source_line 相关的开销信息。
⑨SWAPS:显示交换次数开销信息
4、日常开发需要注意的结论
Status 里面出现的字段:
① converting HEAP to MyISAM 查询结果太大,内存都不够用了往磁盘上搬了。
② creating tmp table 创建临时表:说说创建临时表为什么这么费事呢?首先需要新建临时表,然后需要拷贝数据到临时表,数据推送后需要删除数据,这也就是为什么创建临时表非常损耗性能的原因
③ copying to tmp table on disk 把内存中临时表复制到磁盘,危险!!!这说明临时表都存不下了,只能往磁盘丢
④ locked 锁定了
如果在 show profile 诊断结果中出现了以上 4 条结果中的任何一条,则 sql 语句需要优化。
下面看看临时表的处理过程:
可以看出,拷贝数据到临时表是非常消耗时间的!
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于