(三)MySQL高级

mysql的安装

bit

release 发布版

ga 稳定发布版

第三方软件包,安装在/opt目录下

var/ 变量文件的目录

在linux下检查安装过的软件,rpm -qa|grep -i mysql

永远不要有中文,永远不要有空格

先安装rpm -ivh

getconf LONG_BIT 查看操作系统位数

A temporary password is generated for root@localhost: !/Y/Cw#9IliG

mysql的数据目录 /var/lib/mysql

image-20201215114736454

修改默认的配置文件/etc/my.cnf

修改mysql默认字符集

mysql的二进制日志文件:log-bin

frm 存放表结构

myd 存放数据

myi 存放索引

mysql逻辑架构

image-20201215130920498

mysql引擎

myisam innodb

image-20201215141550073

sql性能下降原因

执行时间长,等待时间长

查询语句烂,索引失效,

索引,单值索引,符合索引,

create index idx_user_name on user(name);

create index idx_user_nameEmail on user(name,email);

关联查询太多join

服务器调优以及个各个参数的设置

常见的join查询

sql的查询顺序

七种join查询

image-20201215143835327

select * from a inner join b on a.key=b.key

image-20201215143948604

select * from a left join ab on a.key=b.key

image-20201215144101061

select * from a right join b on a.key=b.key

[图片上传失败...(image-e5e06-1612330399952)]

select * from a left join b on a.key=b.key where b.key=null

image-20201215145050795

select * from a right join on b a.key=b.key where a.key=null

image-20201215145134339

select * from a full outer join b on a.key=b.key

image-20201215145243494

select * from a full outer join b on a.key=b.key where a.key=null or b.key=null

索引是什么

什么是索引:索引是帮助mysql高效获取数据的数据结构。索引的本质就是一种数据结构,可以简单理解为排好序的快速查找数据结构

在数据外,数据库还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结果上实现高级查找算法,这种数据结构就是索引

image-20201215155514282

索引的优势与劣势

索引的优势:(1)提高数据检索的效率,降低数据库的IO成本,(2)通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗

索引的劣势:(1)实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表记录,所以索引列也要占用空间(2)虽然索引大大提高了查询的速度,同时却会降低更新表的速度,如果对表进行insert,update和delete因为更新表时,需要花时间研究建立最优秀的索引,或优化调整

索引的分类

单值索引:即一个索引只包涵单个列,一个表可以有多个单列索引

唯一索引:索引列的值必须唯一,但允许有空值

复合索引:即一个索引包涵多个列

创建索引的语法:

create [unique] index indexname on tablename(columnname(length));

alter tablename add [unique] index [indexname] on columnname(length);

drop index[indexname] on tablename;

show index from tablename;

索引的数据结构

BTree索引

Hash索引

full-text索引

R-Tree索引

image-20201215163031317

需要建立索引的情况

1.主键自动建立唯一索引

2.频繁作为查询条件的字段应该创建索引

3.查询中与其他表关联的字段,外健索引

4.频繁更新的字段不适合创建索引

5.where条件里用不到的字段不创建索引

6.查询中排序的字段,排序字段若通过排序索引去访问将大大提高排序速度

7.查询中统计或者分组的字段

不需要建立索引的情况

1.表记录太少

2.经常增删改的数据

3,数据大量重复的字段

性能优化

mysql常见的性能瓶颈

explain关键字

(1)查看表的执行顺序

(2)读取数据的操作类型

(3)表之间的引用关系

(4)每张表有多少行被优化器查询

explain+sql语句

explain的表头

image-20201215201750667

explain之id

select 查询的执行顺序,包涵一组数字,表示查询中执行的顺序

值两种情况:

  • 值相同,执行顺序由上至下,

  • 值不同,id越大,越优先被执行

select_type:查询类型

  • 取值情况:

    simple:简单的查询,查询中不包含子查询或者union查询

    primary:查询中如果包涵复杂的查询,最外层的查询,最后加载的查询

    subquery:在where或者select中包涵的子查询

    derived:在临时表中进行查询

    union:若第二个select出现在union之后,则被标记为union,若union包含在from子句的子查询中,外层select将被标记为derived

    union result:从union表中获取结果的select

table:涉及的表名

type:访问类型

(1)type取值类型

all:全表扫描检索

index:全索引扫描

range:只检索给定范围的行,使用索引来选择行,key类显示使用了那些行

ref:非唯一性扫描,通过索引找到满足条件的所有行,可以找多多行结果,

eq_ref:唯一性索引扫描,对于每个索引键可以找到唯一的数据

const:查询条件是主键或者非NULL的UNIQUE索引,表示通过索引能够确定唯一一条数据

system:表只有一行记录,等于系统表,这是const类型的特例,平时不会出现

访问类型从好到差依次为:system>const>eq_ref>ref>range>index>ALL

possible_keys:

可能应用在这张表的索引

key

实际查询使用的索引

key_len

表示索引中使用的字节数,长度越短越好

但是与精确相矛盾,长度越长,匹配结果越精确

ref

查询中与其他表关联的字段,现实使用到的其他表中的索引字段

rows

估算找出所需要的数据需要读取的行数

Extra 包含一些前面没有的信息

  • 类型信息

    Using filesort: mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取,mysql中无法利用索引完成的排序操作叫做文件排序

    using temporary:新建了临时表,mysql在对查询进行过进行排序时使用临时表,常见与order by 或group by

    using index:使用覆盖索引,避免访问表的数据,如果同时出现using where 说明使用索引进行数据的查找,没出现using where说明利用索引读取数据,没有使用索引进行数据的查找

    using where:使用了where

    using join buffer 使用了链接缓存

    impossible where :where 子句的查询结果为false,不能获取元祖

    distinct:优化了distinct

表的读取顺序:

数据读取操作的操作类型:

那些索引可以被引用

那些索引被实际的引用:

表之间的引用

每张表有多少行被优化器

索引的单表优化

索引两表优化

join左链接,右表建立索引

join右链接,左表建立索引

索引三表优化

索引优化,避免索引失效

1.建立索引的顺序与select之后字段出现的顺序相同,即出现全局匹配

2.最佳做前缀匹配法则

3.不要在索引列上进行任何操作,自动或手动的类型转换会产生索引失效

4.存储引擎不能够使用范围条件右边的索引,范围条件之后的索引会失效

5.尽量使用覆盖索引,减少select*

6.尽量不要使用!=,<>,会产生索引失效

7.is null,is not null 也无法使用索引

8.使用模糊查询,通配符不能出现在开头,like %会产生索引失效,使用覆盖索引优化两边都有%的情况

9.字符串不使用单引号会造成索引失效

10.少用or,会产生索引失效

查询截取分析

查询优化过程

1.观察,至少跑一天,查看产生的慢sql情况

2.开启慢查询日志,设置阈值,将慢sql抓取出来

3.explian+慢sql分析

4,show profilie查询SQL在mysql服务器里面的执行细节和生命周期

5,DBA修改sql数据库服务器的参数调优

总结:慢查询的开启并捕获。expalin分析,show profile擦村sql的执行细节,sql数据库 的参数调优

查询与排序优化

(1)小表驱动大表:小的数据集驱动大的数据集

用in与exist

select * from A where id in (select * from B);

select * from A where exists(select 1 from B where A.id = B.id ) 将主查询的结果放入子查询中验证

(2)order by关键字的排序优化,排序顺序与索引顺序相同

如果排序的字段不在索引上,会产生fileSort,排序的方法有两种:双路排序与单路排序

双路排序:先读取排序的字段在内存中排序,然后排好的顺序在表中读取数据

单路排序:从磁盘读取所有需要的列,在内存中排序后输出,但是在大数据量的情况下会多次读取

如果多次读取,需要扩大sort_buffer和sort_length的大小

(3)group by实质是先排序后分组,也遵循索引的最左前缀匹配原则

无法使用索引列时,增大max_length_for_sort_data参数的设置,增加唉sort_buffer_size参数的设置

慢查询日志:用于记录mysql相应时间超过阈值的语句

手动开启:show variables like '%slow_query_log%';

set global slow_query_log=1;

set slow_query_log_path=/var/lib/mysql/slow.log

show variables like 'long_query_time%'

set global long_query_time=4

/var/lib/mysql/下保留慢查询日志

mysql慢日志的分析工具mysqIdumpslow

得到返回结果最多的10个SQL:mysqldumpslow -s r -t 10 /var/lib/mysql/slow.log

得到使用最频繁的10个SQL:mysqldumpslow -s c -t 10 /var/lib/mysql/slow.log

得到按时间排序最多的10个SQL:mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log

得到返回结果最多,且查询语句中包含left jion的10个SQL:mysqldumpslow -s r -t 10 -g "left jion" /var/lib/mysql/slow.log

image-20201221120819103

批量数据脚本,函数与存储过程

show profile:mysql用来分析当前会话中语句执行的资源消耗情况,可以用于sql的调优的测量

开启profile:

1.查看是否支持 show variables like 'profiling';

2.开启profile set profiling=1;

3.运行sql

4.查看结果:show profiles;

image-20201221163535587

5.诊断sql

image-20201221164205333

show profile cpu,block io ,for query 3;

image-20201221163750531

危险的status

image-20201221164317184

全局查询日志

命令 set globel general_log=1;

set globel log_output='TABLE';

数据库锁理论

锁的分类

  • 读锁:共享锁,多个读操作可以同时进行

  • 写锁:排他锁,当前写操作没有完成前,他会阻断其他操作

  • 表锁:(偏读)锁粒度大,发生锁冲突的概率最高,并发度最低

-- 增加表锁: lock table 表名 1read(write),表名2read(write),其他

-- 查看表上加过的锁 show open tables;

-- 释放锁:unlock tables;

-- 表锁分析

show open tables;

show status like 'table%';

  • 锁定一行:begin;

    ​ select *from table where id=8 for update;

    ​ commit;

    行锁分析:show status like 'innodb_row_lock%';

    image
image-20201221202123589

MySIAM

mylock1 (read) mylock2

select mylock1 可以 select mylock1 可以

insert mylock1 不可以 insert mylock1 阻塞

select mylock2 不可以

mylock1 (write) mylock2

select mylock1 不可以 select mylock1 阻塞

insert mylock1 可以 insert mylock1 阻塞

select mylock2 不可以

行锁

innoDB

读己之所写,其他session读取不到

写锁相互互斥,操作同一行会阻塞

索引失效,行锁升级为表锁

间隙锁的危害

当使用范围条件而不是相等条件检索数据,innnoDB会给在这个范围内的索引项进行加锁,对于键值在这个范围内,但是不存在的记录,也会加锁,这就是间隙锁(next_key锁)

如何锁定一行

begin;
select * from table_name where id =8  for update;
commit;

行锁的分析

show status like 'innodb_row_lock%'

image-20210202231059120
image-20210202231114544

主从复制

复制的基本原理

salve会从master读取binlog来进行数据同步

三步骤+原理图:

image-20201221202724283

复制的基本原则:

每个slave只有一个master

每个slave只能有唯一的服务器ID

每个master可以有多个salve

主机修改my.cnf文件

1.配置主服务器唯一ID servier-id=1

2.开启二进制日志 log-bin

3.启用错误日志 log-err

4.根目录baseidr

5.临时目录

6.数据目录

7.配置不需要复制的数据库 binlog-ignore-db

8.配置需要复制的库 binlog-do-db

image-20210203130342221
image-20210203130635584
image-20210203130814211

从机修改my.cnf文件

1.修改从服务器ID

image-20210203131058842

2.开启二进制文件复制

image-20210203131036133

3.主机建立账户并授权slave

mysql>GRANT REPLICATION SLAVE ON *.* TO 'zhangsan'@'从机数据库IP' IDENTIFED BY '123456';

4.主机刷新一下

mysql>flush privileges;

5.show查看主机的复制状态,主要记录File和Position的值

image-20210203131622543

6.在linux上配置需要复制的主机

image-20210203131848347

7.开启从机 start slave

image-20210203132010065

你可能感兴趣的:((三)MySQL高级)