简介
RPM安装
上传至linux主机,查看是否安装过 rpm -qa|grep -i mysql
安装server rpm -ivh MySQL-server-5.5.48-1.linux2.6.x86_64.rpm
安装client
报错
libncurses.so.5()(64bit) 被 MySQL-client-5.5.48-1.linux2.6.x86_64 需要
使用命令dnf install ncurses-compat-libs
安装后解决
查看安装 mysqladmin --version
服务启动service mysql start
服务关闭 service mysql stop
查看运行ps -ef|grep mysql
root密码设置和开机自启
top
查看linux 开机时间
给root用户设置mysql密码 /usr/bin/mysqladmin -u root password 123456
设置开机启动chkconfig mysql on
查看 启动配置 chkconfig --list | grep mysql
安装位置
ps -ef|grep mysql
[root@VM-0-12-centos opt]# ps -ef|grep mysql
root 44637 1 0 14:50 pts/0 00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/VM-0-12-centos.pid
mysql 44737 44637 0 14:50 pts/0 00:00:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/lib/mysql/VM-0-12-centos.err --pid-file=/var/lib/mysql/VM-0-12-centos.pid
root 93400 1915 0 15:16 pts/0 00:00:00 grep --color=auto mysql
修改字符集
单独拷贝出配置文件,默认的不动,重新启动mysql
插入中文字符,查询是乱码
查看字符集设置show variables like '%char%';
编辑 /etc/my.cnf
[client]
default-character-set=utf8
[mysqld]
character_set_server=utf8
character_set_client=utf8
collation-server=utf8_general_ci
[mysql]
default-character-set=utf8
之前的表还是乱码,新建一个表后 字符集 正确不乱码了
mysql 配置文件
主要配置文件
1、二进制日志log-bin 主要用于主从复制,windows目录中my.ini文件中 linux 在/etc/my.cnf
2、错误日志 log-error 默认是关闭的,疾苦严重的警告信息和错误信息,每次启动和关闭的详细信息等
3、查询日志 默认关闭,记录查询等sql语句,如果开启会降低mysql等整体性能,因为日志也是需要消耗系统资源的
数据文件
mysql逻辑架构简介
和其他数据库相比嘛,MySQL有点与众不同,他的架构可以在多种不同的场景中应用并发挥良好作用。主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其他的系统任务以及数据的存储提取相分离。
这种架构可以根据业务的需求和实际需要选取合适的存储引擎
mysql逻辑架构示意图
存储引擎介绍
默认的存储引擎和当前在用存储引擎
MyISAM和InnoDB
索引优化分析
SQL性能下降的原因
SQL执行加载顺序
人的书写顺序
mysql的读顺序
七种join理论
按顺序记忆
七种join的SQL编写
先创建数据库 create database db0629
切换至此库 use db0629
创建表
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`)
)ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8;
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 CHARACTER SET = utf8;
插入数据
insert into tbl_dept values(null,'RD',1);
insert into tbl_dept values(null,'HR',12);
insert into tbl_dept values(null,'MK',13);
insert into tbl_dept values(null,'MIS',14);
insert into tbl_dept values(null,'FD',15);
insert into tbl_emp values(null,'z3',1);
insert into tbl_emp values(null,'z4',1);
insert into tbl_emp values(null,'z5',1);
insert into tbl_emp values(null,'w5',2);
insert into tbl_emp values(null,'w6',2);
insert into tbl_emp values(null,'s7',3);
insert into tbl_emp values(null,'s8',4);
insert into tbl_emp values(null,'s9',51);
全有连接 ,mysql 没有 full out 这个语法,oracle有,解决办法就是 左右全外链接去重
select * from tbl_emp a right join tbl_dept b on a.deptId=b.id union select * from tbl_emp a left join tbl_dept b on a.deptId=b.id;
mysql> select * from tbl_emp a right join tbl_dept b on a.deptId=b.id
-> union
-> select * from tbl_emp a left join tbl_dept b on a.deptId=b.id;
+------+------+--------+------+----------+--------+
| id | name | deptId | id | deptName | locAdd |
+------+------+--------+------+----------+--------+
| 1 | z3 | 1 | 1 | RD | 1 |
| 2 | z4 | 1 | 1 | RD | 1 |
| 3 | z5 | 1 | 1 | RD | 1 |
| 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 | s9 | 51 | NULL | NULL | NULL |
+------+------+--------+------+----------+--------+
各自独有查询,左右外链接去重
mysql> select * from tbl_emp a right join tbl_dept b on a.deptId=b.id where a.deptId is null union 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 | locAdd |
+------+------+--------+------+----------+--------+
| NULL | NULL | NULL | 5 | FD | 15 |
| 8 | s9 | 51 | NULL | NULL | NULL |
+------+------+--------+------+----------+--------+
索引是什么
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。可以得到索引的本质:索引是数据结构。
Index在数组里叫下标、在git里叫暂存区库。
索引的目的在一提高查询效率,可以类比字典
排好序的快速查找数据结构
一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。
我们常说的索引,如果没有特别指明,都是指B树(多路搜索树,并不一定是二叉的)结构组织的索引。
其中聚集索引,次要索引,覆盖索引,符合索引,前缀索引,唯一索引默认都是使用B+树索引,统称索引。当然,除了B+树这种类型的索引之外,还有哈希索引(hash index)等。
索引的优势劣势
索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间艳绝建立最优秀的索引,或优化查询。
索引分类和建索引命令语句
建议:一张表最多不要超过5个索引
单值索引:即一个索引只包含单个列,一个表可以有多个单列索引(大部分情况下,建符合索引优于单值索引)
唯一索引:索引列的值必须唯一
,但允许有空值
复合索引即一个索引包含多个列
基本语法
创建、 CREATE [UNIQUE] INDEX indexName ON mytable(columnname(length))
ALTER mytable ADD [UNIQUE] INDEX [indexName] ON (columnname(length))
删除、DROP INDEX [indexName] ON mytable;
查看、SHOW INDEX FROM table_name\G
有四种方式来添加数据表的索引
ALTER TABLE tbl_name ADD PRIMARY KEY(column_list);
改语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。
ALTER TABLE tbl_name UNIQUE index_name(column_list);
这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。
ALTER TABLE tbl_name ADD INDEX index_name(column_list);
添加普通索引,索引值可以出现多次。
ALTER TABLE tbl_name ADD FULLTEXT index_name(column_list);
改语句指定了索引为 FULLTEXT
,用于全文索引。
BTree索引 索引结构和检索原理
BTree索引
检索原理
哪些情况适合建索引
1、主键自动建立唯一索引
2、频繁作为查询条件的字段应该创建索引
3、查询中与其他表关联的字段,外键关系建立索引
4、频繁更新的字段不适合创建索引,因为每次更新不单单是更新了记录还会更新索引。
5、Where条件里用不到的字段不创建索引
6、单键/复合索引的选择问题。who?(在高并发下倾向创建组合索引)
7、查询中排序的字段,排序字段若通过索引区访问将大大提高排序速度。
8、查询中统计或者分组字段
哪些情况不合适建索引
1、表记录太少,300w条性能开始下降。
2、经常增删改的表,因为索引提高了查询速度,同时会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE,MySQL不仅要保存数据,还要保存一下索引文件
3、数据重复且分布平均的表字段,应该只为最经常查询和最经常排序的数据建立索引。值得注意的是,如果某个数据列包含许多重复的内容,为它建立索引就没有太大的时机效果。
性能分析
性能分析前提知识
MySQL逻辑架构 第二层,服务层MySQL自带的查询优化器 MySQL Query Optimizer
MySQL常见瓶颈
explain使用简介
explain是什么:使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈
获取到的执行计划包含的信息
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|
explain 之 id 介绍
select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序,三种情况
1、id相同,执行顺序由上至下
2、id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
3、id相同和不同,同时存在
explain之select_type和table介绍
select_type有哪些
1、SIMPLE:简单的select查询,查询中不包含子查询或者UNION
2、PRIMARY:查询中若包含任何复杂的子查询,最外层查询则被标记为PARIMARY,也就是最后加载的那一个
3、SUBQUERY:在SELECT或WHERE列表中包含了子查询(就是子查询)
4、DERIVED:在FROM列表中包含的子查询被标记为DERIVED(衍生)MySQL会递归执行这些子查询,把结果放在临时表里。
5、UNION:若第二个SELECT出现在UNION之后,则被标记为UNION;若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED
6、UNION RESULT:从UNION表获取结果的SELECT(UNION获取到的结果)
explain之type介绍
type的值有哪些
ALL | index | range | ref | eq_ref | const,system | NULL |
---|
显示查询使用了何种类型,从好到最差依次是:
system | const | eq_ref | ref | range | index | ALL |
---|
一般来说,得保证查询至少达到range级别,最好能达到ref
system:
表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,这个可以忽略不计
const
:表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快,如将主键置于where列表中,MySQL就能将改查询转换为一个常量
如下查询,先加载t1,d1 衍生 至 t1 因为括号内的查询为主键查询,主键唯一,所以类型为const,外层衍生查询,因为括号内只返回了一条数据,如上所说,只有一行数据的查询就是system类型。(这种查询毫无意义,可以忽略)
eq_ref
:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描 (意思是等于查询,且只有一条记录)
ref
:非唯一性扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个复合条件的行,所以他应该属于查找和扫描的混合体。(意思就是等于值的查询)
range
:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引,一般就是在的where语句中出现了between、<、>、in等等查询,这种范围扫描索引扫描比全表扫描好,因为它只需要开始于索引等某一点,而结束于另一点,不用扫描全部索引。(意思就是用了 区间值的查询)
index
:Full Index Scan,index与ALL区别为index类型只便利索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和index都是读全表
,但index是从索引中读取的,而all是从硬盘中读取的)
all
:Full Table Scan, 遍历全表以找到匹配的行
一般来说,得保证查询至少达到range级别,最好能达到ref
explain之possible_keys和key介绍
possible_keys
:显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用
。
key
:实际使用的索引。如果为NULL,则没有使用索引,查询中若使用了覆盖索引,则该索引仅出现在key列表中
查询中若使用了覆盖索引,则该索引仅出现在key列表中
覆盖索引的意思是,这次查询的字段中的索引都用到了
explain之key_len介绍
表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好,key_len显示的值为索引字段的最大可能长度,并非实际使用长度
,即key_len是根据表定义计算而得,不是通过表内检索出的。(意思就是查询语句中索引字段的长度)
explain之ref介绍
显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值。(列出被使用的字段 库.表.字段
const
具体的值)
explain 之rows介绍
根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数
explain 之 Extra 介绍
包含不适合在其他列中显示但十分重要的额外信息
Using filesort
: 说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作成为“文件排序”
第一条查询extra 产生了文件内排序,排序的时候最好遵循所建索引的顺序和个数,否则会产生文件内排序,第二条根据所建索引顺序和个数优化后 没有了文件内排序
Using temporary
:使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表常见于排序 order by 和 group by。
Using index
:表示相应的select操作中使用了覆盖索引,避免访问了表的数据行,效率不错。如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有同时出现using where,表明索引用来读取数据而非执行查找动作。
覆盖索引
:理解一,select的数据列只用从索引中就能取得,不必读取数据行,MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件,换句话说查询列刚好被所建的索引覆盖
建好的复合索引 idx_clo1_col2_col3,查得也是这个三个字段,索引的个数和顺序匹配这就叫覆盖索引
注意,如果要使用覆盖索引,一定要注意select列表中只取出需要的列,不可 select *
因为如果将所有字段一起做所有会导致索引文件过大,查询性能下降
前三种最重要
Using where
:使用了where
Using join buffer
:使用了连接缓存,join用的多,配置文件中的join buffer 可以调大点
impossible where
:where子句点值总是false,不能用来获取任何元组
select tables optimized away
:在没有GROUPBY子句点情况下,基于优化MIN/MAX操作或者对于MyISAM 存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
distinct
:优化distinct操作,再找到第一匹配的元组后即停尸找同样值的动作
explain 之热身case