二、索引优化分析
1.SQL性能下降的原因
单值索引:在user表中的name字段上建索引
create index idx_user_name on user(name)
复合索引:在user表中的name字段和email字段上建索引
create index idx_user_nameEmail on user(name,email)
2.常见的Join查询
sql的执行顺序
首先我们手写的sql语句如下:
select distinct
from
join on
where
group by
having
order by
limit
mysql的执行顺序如下:
from
on
join
where
group by
having
select
distinct
order by
limit
sql执行顺序总结如下
七种Join连接
内连接 select from tableA A inner join tableB B on A.key=B.key
左外连接 select from tableA A left join tableB B on A.key=B.key
左连接 select from tableA A left join tableB B on A.key=B.key where B.key is null
右外连接 select from tableA A right join tableB B on A.key=B.key
右连接 select from tableA A right join tableB B on A.key=B.key where A.key is null
全连接 select from tableA A full outer join tableB B on A.key = B.key
select from tableA A full outer join tableB B on A.key=B.key where A.key is null or B.key is null
Linux编写Join语句
建表语句
CREATE TABLE `tbl_dept`(`id`INT(11)NOT NULL AUTO_INCREMENT,
`deptName` VARCHAR(30) DEFAULT NULL,
`IocAdd` 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` foreign key(`deptId`) references `tbl_dept`(`id`)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO tbl_dept(deptName,IocAdd)VALUES('RD',11);
INSERT INTO tbl_dept(deptName,IocAdd)VALUES('HR',12);
INSERT INTO tbl_dept(deptName,IocAdd)VALUES('MK',13);
INSERT INTO tbl_dept(deptName,IocAdd)VALUES('MIS',14);
INSERT INTO tbl_dept(deptName,IocAdd)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('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);
部门表
mysql> select * from tbl_dept;
+----+----------+--------+
| id | deptName | IocAdd |
+----+----------+--------+
| 1 | RD | 11 |
| 2 | HR | 12 |
| 3 | MK | 13 |
| 4 | MIS | 14 |
| 5 | FD | 15 |
+----+----------+--------+
5 rows in set (0.00 sec)
员工表
mysql> select * from tbl_emp;
+----+------+--------+
| id | name | deptId |
+----+------+--------+
| 1 | z3 | 1 |
| 2 | z4 | 1 |
| 3 | z5 | 1 |
| 4 | w5 | 2 |
| 5 | w6 | 2 |
| 6 | s7 | 3 |
| 7 | s8 | 4 |
| 8 | s9 | 51 |
+----+------+--------+
8 rows in set (0.00 sec)
内连接如下
mysql> select * from tbl_emp a inner join tbl_dept b on a.depTId = b.id;
+----+------+--------+----+----------+--------+
| id | name | deptId | id | deptName | IocAdd |
+----+------+--------+----+----------+--------+
| 1 | z3 | 1 | 1 | RD | 11 |
| 2 | z4 | 1 | 1 | RD | 11 |
| 3 | z5 | 1 | 1 | RD | 11 |
| 4 | w5 | 2 | 2 | HR | 12 |
| 5 | w6 | 2 | 2 | HR | 12 |
| 6 | s7 | 3 | 3 | MK | 13 |
| 7 | s8 | 4 | 4 | MIS | 14 |
+----+------+--------+----+----------+--------+
7 rows in set (0.03 sec)
左外连接如下
mysql> select * from tbl_emp a left join tbl_dept b on a.depTId = b.id;
+----+------+--------+------+----------+--------+
| id | name | deptId | id | deptName | IocAdd |
+----+------+--------+------+----------+--------+
| 1 | z3 | 1 | 1 | RD | 11 |
| 2 | z4 | 1 | 1 | RD | 11 |
| 3 | z5 | 1 | 1 | RD | 11 |
| 4 | w5 | 2 | 2 | HR | 12 |
| 5 | w6 | 2 | 2 | HR | 12 |
| 6 | s7 | 3 | 3 | MK | 13 |
| 7 | s8 | 4 | 4 | MIS | 14 |
| 8 | s9 | 51 | NULL | NULL | NULL |
+----+------+--------+------+----------+--------+
8 rows in set (0.10 sec)
右外连接如下
mysql> select * from tbl_emp a right join tbl_dept b on a.depTId = b.id;
+------+------+--------+----+----------+--------+
| id | name | deptId | id | deptName | IocAdd |
+------+------+--------+----+----------+--------+
| 1 | z3 | 1 | 1 | RD | 11 |
| 2 | z4 | 1 | 1 | RD | 11 |
| 3 | z5 | 1 | 1 | RD | 11 |
| 4 | w5 | 2 | 2 | HR | 12 |
| 5 | w6 | 2 | 2 | HR | 12 |
| 6 | s7 | 3 | 3 | MK | 13 |
| 7 | s8 | 4 | 4 | MIS | 14 |
| NULL | NULL | NULL | 5 | FD | 15 |
+------+------+--------+----+----------+--------+
8 rows in set (0.00 sec)
左连接如下
mysql> select * from tbl_emp a left join tbl_dept b on a.depTId = b.id where b.id is null;
+----+------+--------+------+----------+--------+
| id | name | deptId | id | deptName | IocAdd |
+----+------+--------+------+----------+--------+
| 8 | s9 | 51 | NULL | NULL | NULL |
+----+------+--------+------+----------+--------+
1 row in set (0.03 sec)
右连接如下
-+------+--------+----+----------+--------+
| id | name | deptId | id | deptName | IocAdd |
+------+------+--------+----+----------+--------+
| NULL | NULL | NULL | 5 | FD | 15 |
+------+------+--------+----+----------+--------+
1 row in set (0.00 sec)
全有如下
mysql> select * from tbl_emp a left join tbl_dept b on a.depTId = b.id
-> union
-> select * from tbl_emp a right join tbl_dept b on a.depTId = b.id;
+------+------+--------+------+----------+--------+
| id | name | deptId | id | deptName | IocAdd |
+------+------+--------+------+----------+--------+
| 1 | z3 | 1 | 1 | RD | 11 |
| 2 | z4 | 1 | 1 | RD | 11 |
| 3 | z5 | 1 | 1 | RD | 11 |
| 4 | w5 | 2 | 2 | HR | 12 |
| 5 | w6 | 2 | 2 | HR | 12 |
| 6 | s7 | 3 | 3 | MK | 13 |
| 7 | s8 | 4 | 4 | MIS | 14 |
| 8 | s9 | 51 | NULL | NULL | NULL |
| NULL | NULL | NULL | 5 | FD | 15 |
+------+------+--------+------+----------+--------+
9 rows in set (0.00 sec)
其中union关键字表示合并去重。
A表和B表独有
mysql> select * from tbl_emp a left join tbl_dept b on a.depTId = b.id where b.id is null union select * from tbl_emp a right join tbl_dept b on a.depTId = b.id where a.deptId is null;
+------+------+--------+------+----------+--------+
| id | name | deptId | id | deptName | IocAdd |
+------+------+--------+------+----------+--------+
| 8 | s9 | 51 | NULL | NULL | NULL |
| NULL | NULL | NULL | 5 | FD | 15 |
+------+------+--------+------+----------+--------+
2 rows in set (0.00 sec)
3.索引简介
索引是什么
官方定义:索引(mysql)是帮助MySql高效获取数据的数据结构,可以说索引的本质:索引是数据结构。
索引的目的在于提高效率,可以类比字典,如果查“mysql”这个单词,先定位m字母,再定义y,再sql,如果没有索引,可能就是a–z。
索引:就是排好序的快速查找数据结构。(索引会影响sql语句中的where和order by)。
详解索引
在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这个数据结构,就是索引。
一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往都是以索引文件的形式存储在磁盘上。
通常所说的索引是B树(多路搜索树,不一定是二叉树)结构组织的索引。
索引的优势
索引的劣势
mysql索引分类
单值索引:一个索引只包含单个列,一个表可以有多个单列索引
唯一索引:索引列的值必须唯一,但允许有空值
复合索引:一个索引包含多个列
基本语法
使用alter命令添加数据表的索引
那些情况需要创建索引
那些情况不需要创建索引
4.Mysql性能优化-explain的使用
使用方法
explain+SQL语句,实例如下
mysql> mysql> explain select * from tbl_emp;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | tbl_emp | ALL | NULL | NULL | NULL | NULL | 8 | NULL |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
使用explain能做什么
使用explain产生的表头名词解释如下
id
select查询的序列号,包含了一组数字,表示查询中执行select字句或操作表的顺序,其中id的值有三种情况。
id相同:执行顺序由上至下
id不相同:如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
id相同不同。同时存在:id值越大优先级越大,越先执行,id相同顺序执行
从id可以看出表的执行顺序,所以使用explain可以改变表的执行顺序(sql语句是t1,t2,t3.使用explain可能执行顺序是t3,t1,t2等)
select_type
select_type查询类型,主要用于区别普通查询、联合查询、子查询等的复杂查询,值有6种情况,如下
使用前面的tbl_emp表和tbl_dept表为例,如下
mysql> explain select * from tbl_emp a left join tbl_dept b on a.deptId = b.id union select * from tbl_emp a right join tbl_dept b on a.deptId = b.id;
+----+--------------+------------+------+---------------+------------+---------+----------------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+------------+------+---------------+------------+---------+----------------+------+----------------------------------------------------+
| 1 | PRIMARY | a | ALL | NULL | NULL | NULL | NULL | 8 | NULL |
| 1 | PRIMARY | b | ALL | PRIMARY | NULL | NULL | NULL | 5 | Using where; Using join buffer (Block Nested Loop) |
| 2 | UNION | b | ALL | NULL | NULL | NULL | NULL | 5 | NULL |
| 2 | UNION | a | ref | fk_dept_id | fk_dept_id | 5 | mysqltest.b.id | 1 | NULL |
| NULL | UNION RESULT | | ALL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+------+---------------+------------+---------+----------------+------+------------------------------------------------
type
访问类型排列,显示查询使用了何种类型,从好到差依次为
system>const>eq_ref>ref>range>index>all