有关于MySQL的高级部分笔记
这是一篇关于MySQL高级部分的笔记主要是,sql优化以及mysql锁的相关内容,以及主从配置等内容等比较基础的优化mysql
1、逻辑架构部分
-
逻辑架构ios
逻辑架构介绍图以下sql
-
链接层:最上层是一些客户端和链接服务,包含本地的sock通信大多时基于客户端/服务端工具实现的相似于tcp/ip的通信数据库
-
服务层:完成大多数的核心服务的功能,如,SQL接口,并完成缓存的查询SQL的分析和优化以及部份内置函数的执行,全部款存储引擎的功能api
-
引擎层:存储引擎真正的负责了MySQL中的数据的存储和提取,服务器经过api与存储引擎进行通信,经常使用的有MyISAM和InnoDB缓存
-
存储层:数据存储在裸设备上,并完成与存储引擎的交互服务器
优化主要是只使SQL的解析格式符合优化器的优化格式数据结构
-
存储引擎架构
查看mysql的存储引擎命令并发
# 看你的mysql提供了生么存储引擎
show engines;
# 看当前默认的存储引擎
show variables like '%storage_engine%';MyISAM与InnoDB的对好比下表
对比项 MyISAM InnoDB 主外键 不支持 支持 事务 不支持 支持 行表锁 表锁,即便操做一条记录也会锁住整个表,不适合高并发的操做 行锁,操做时只锁某一行,不对其余的行有影响,适合高并发的操做 缓存 只缓存索引不缓存真实数据 不只缓存索引还要缓存真实数据,对内存的要求比较高,并且内存的大小对性能有决定性的影响 表空间 小 大 关注点 性能 事务 默认安装 Y Y -
性能降低SQL慢的缘由
-
查询语句写的烂
-
索引失效
-
单值索引
-
符合索引
-
-
关联查询太多join(设计缺陷)
-
服务器调优及各个参数的设置(缓冲、线程数等)
-
-
SQL执行加载的顺序
-
手写顺序
select distinct
<select_list>
from
<left_table> <join_type>
join <right_tablr> on <join_condition>
where
<where_condition>
group by
<group_by_list>
having
<having_condition>
order by
<order_by_condition>
limit <limit_number> -
MySQL的执行
from <left_table>
on <join_condition> <join_type>
join <right_table>
where <where_condition>
group by <group_by_list>
having <having_condition>
select
distinct <select_list>
order by <order_by_condition>
limit <limit_number>
总结
-
2、索引及优化部分
-
索引简介
-
是什么
索引是帮助MySQL高效获取数据的数据结构,本质上是数据结构(查找+排序)
-
种类
B+树索引
hash索引
全文索引
RTree索引
-
优点
提升数据的检索效率下降的磁盘的io
下降数据的排序成本下降了cpu的消耗
-
劣势
实际上索引也是一张表,保存主键与索引字段,指向实体表的记录,也是要占用空间的
会下降对于insert,update,delete的速度
索引只是提升效率的一个因素
-
分类
-
单值索引:一个索引只包含一个列
-
惟一索引:索引的列必须惟一,能够有空值
-
复合索引:一个索引包含多个列
-
基本语法
# 建立
create [unique] index indexName on table(columnname(length));
alter tablename add [unique] index indexname on (columnname(length));
# 删除
drop index [indexname] on tablename;
# 查看
show index from tablename\G
-
-
哪些状况适合建索引
-
主键自动创建惟一索引
-
频繁做为查询条件的字段
-
查询中与其余表关联的字段,外键关系创建索引
-
频繁更新的字段不适合创建索引
-
where用不到的字段不建立索引
-
单键/组合索引的选择问题(高并发下倾向于建立复合索引)
-
查询中排序的字段排序字段经过索引访问将大大提升访问的速度
-
查询中统计和分组的字段
-
-
哪些状况不适合建索引
-
表记录太少
-
频繁修改的字段
-
数据重复且分布平均的字段
-
-
性能分析
MySQL Query Optimizer 查询优化器
负责对select语句进行优化
性能瓶颈
cpu:cpu饱和的时候通常发生在数据装入内存或者从磁盘上读取数据的时候
io:装入数据元大于内存容量的时候
服务器硬件:top,free,iostat,vmstat命令查看系统的性能状态
-
3、Explain 执行计划
-
是什么
使用explain关键字能够模拟优化器执行sql查询语句,从而知道,MySQL是如何处理你的sql语句的分析你的查询语句或是表结构的性能瓶颈
-
怎么用
explain + sql
执行计划包含的信息
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
-
字段解释
id
id:select查询的序列号,包含一组数字表示查询中执行select子句或操做表的顺序
三种状况:id相同执行顺序由上至下
id不一样若是是子查询,id的序号会递增,id越大优先级越高,越先被执行
id相同又不一样会遵循上两条规律
select_type
select_type: 查询的类型主要是用于区别,普通查询,联合查询,子查询等复杂查询
simple:简单查询不包含子查询,或者union
primary:主查询子查询最外层的查询
subquery:子查询
derived:在from列表中包含的子查询被标记为dervied衍生,MySQL会递归执行这些子查询,把最终结果放在临时表里
union:第二个select出如今union以后则被标记为union,若union包含在from子句中,外层的select将被标记为derived
union result:从union表中获取结果的select
table 显示这一行数据是关于那一张表的
type
常见的访问类型八种
all | index | range | ref | eq_ref | const,system | null |
---|---|---|---|---|---|---|
全表扫描 | 全索引扫描比all好 | 检索指定范围的行 | 非惟一性索引扫描,多条记录匹配 | 惟一性索引扫描,表中只有一条记录匹配常见于主键索引惟一索引 | system表只有一行记录 const表示经过索引一次就找到了觉得只匹配一行数据 如将主键置于where列表中,MySQL就能将查询转化为const |
最好到最差
system > const > eq_ref > ref > range > index > all
通常来讲得保证查询至少优化到range最好到ref
prossiable_keys和key
prossiable_keys:显示出在本次查询中可能用到的索引,可是不必定用
keys:实际查询的过程当中实际使用的索引为null没有使用索引,若查询中使用覆盖索引则在该索引仅出如今key列表中
key_len
索引字段的最大可能长度,并不是实际长度,再不损失精确性的状况下越小越好
ref
显示索引的那一列被使用了,若是可能的话尽可能是个常数
rows
找到所需的记录读取的行数
extra
很重要的额外信息
using filesort:使用文件内排序(坏)
using temporary:使用临时文件(坏)
using index:使用索引(好)
using where:使用where
4、优化的几点建议
-
全值匹配
-
最佳左前缀法则
-
不在索引列上作任何的操做(计算,函数,(自动or手动的类型转换)),会致使索引失效而全表扫描
-
存储引擎不能使用索引中范围条件右边的列
-
尽可能使用覆盖索引只访问索引的查询(索引列与查询列一致),减小select *
-
mysql在使用不等于(!= 或 <>)的时候没法使用索引回单之全表扫描
-
is null ,is not null 也没法使用索引
-
like以通配符开头会致使索引失效全表扫描
-
字符串不单引号索引失效
-
少用or用来链接时会使索引失效
-
永远小表驱动大表
-
group by/order by排序字段也会用到索引(左前缀,尽可能使用where)
5、查询截取分析
-
慢查询日志截取慢sql
# 查看
show variables like '%slow_query_log%';
# 开启
set global slow_query_log=1
# 查看记录sql的阈值时间
show variables like 'long_query_time%';
# 设置阈值时间
set global long_query_time=3; -
show profile
# 查看是否支持
show variables like 'profiling'
# 开启
set profiling=on
# 查看结果
show profiles;
show profile cpu,block io from query [问题sql的query_id];
6、MySQL锁机制
-
概念
锁是计算机协调锁个进程或者线程并发访问某一资源的机制
-
分类
读锁/写锁
-
读锁:共享锁
-
写锁:排它锁
表锁/行锁
-
表锁:锁整张表(偏读,偏向MyISAM存储引擎,开销小,加锁快,无死锁,锁定的粒度大,大,发生锁冲突的几率高,并发度低)
-
行锁:锁一行(偏写,偏向InnoDB存储引擎,开销大,加锁慢会出现死锁,锁定的粒度小,发生锁冲突的几率最低,并发度也高)
-
事务及ACID属性
事务是由一组SQL语句组成的逻辑处理单元,事物具备如下四个属性
-
原子性(Atomicity):事务是一个原子性的操做单元,其对数据的修改,要么全都执行,要么全都不执行
-
一致性(Consistent):在事务开始和完成时,数据都必须保持一致的状态,这意味着,全部相关的数据规则都必须应用于事务的修改,以保持数据的完整性,十五届数值,全部的内部数据(如b树索引或双向链表)也都必须是正确的
-
隔离性(Isolation):数据库系统提供必定的隔离机制,保证十五在不收外部并发操做的影响的“独立”环境执行,这意味着事务处理过程当中的中间状态对外部是不可见的,反之亦然
-
持久性(Durable):事务完成以后,它对数据的修改是永久性的,即便出现系统故障也可以保持
并发处理带来的问题
-
更新丢失:相似于版本覆盖
-
脏读:读到已修改还没有提交的数据
-
不可重复读:两次读的不同
-
幻读:事务a读到了事务b提交新增的数据不符合隔离性
数据库的事务隔离级别
数据库的隔离级别 数据一致性 脏读 不可重复读 幻读 读未提交 最低级别,只能保证不读物理损坏的数据 Y Y Y 读已提交 语句级 N Y Y 可重复读 事务级 N N Y 可序列化 最高级别,事务级 N N N # 查看数据库的隔离级别 MySQL默认为可重复读
show variables like 'tx_isolation';
# 锁定一行
begin;
sql+for update;
commit; -
# 建表
create table mylock(
id int not null primary key auto_increment,
name varchar(20)
) engine myisam;
# 插入数据
insert into mylock(name) values('a'),('b'),('c'),('d'),('e');
select * from mylock;
# 手动增长表锁
lock table 表名1 read,表名2 write;
# 查看表的加锁状态
show open tables;
# 解锁
unlock tables; -