mysql总结:存储引擎,树的区别,索引,性能分析,锁,事务,大批量数据插入优化

1、存储引擎

常见存储引擎

  • Myisam:5.5之前默认引擎,支持表锁,不支持外键和事务,访问速度快

  • InnoDB:支持事务,外键,支持行级锁,5.5之后默认存储引擎,5.6之后支持全文索引

  • Memory:所有数据置于内存中,拥有极高的效率,但是重启数据会丢失,默认hash索引

  • Archive:拥有很快的插入速度,但是查询相对差劲

  • Federated:将不同的mysql服务器联合,逻辑形成一个完整的数据库,适合分布式场景

逻辑存储结构

  • 表空间:ibd文件

  • 段:数据段,索引段,回滚段

  • 区:每个区1M,一个区64页

  • 页:存储引擎磁盘管理的最小单元,每页16k,

  • 行除了定义字段,还包含隐藏字段,事务id,回滚指针,隐藏主键id(没有主键情况下)

  • 每次申请四到五个区,以保证页的连续性

2、树的区别

  • 二叉树:可能产生不平衡,顺序数据可能会出现链表结构,层级太深

  • 平衡二叉树:需要频繁自旋,维护结构,性能根据层级而定,性能不稳定

  • b+tree:

    • 主键聚簇叶子节点存放索引和数据(单向链表维护叶子节点,MySQL优化为了双向链表),非叶子节点存放索引,便于区间查询,排序

    • 插入演示:B+ Tree Visualization (usfca.edu)

  • 红黑树:
    • 层级不确定,无法评估除响应时间
    • 不支持范围查询
  • 二级索引非叶子节点存放索引,叶子节点存放索引和主键

3、索引

索引概述

  • 索引是高效获取数据的数据结构

索引结构

  • B+Tree(),两层1.8w,三层可存储2200w左右记录

  • Hash(不支持范围查询,无法利用索引完成排序,精准匹配效率极高,只需匹配一次即可定位到数据)

索引优缺点

优点

  • 大大加快查询速度

  • 使用分组和排序时候可以显著减少分组和排序时间

  • 唯一索引可以保证字段唯一

  • 可以加速表与表之间的连接

缺点

  • 创建和维护索引需要消耗时间,随着数据量增加时间也会增加

  • 占用磁盘空间

  • 对表进行urd操作时候也要动态维护,urd性能会下降

创建索引原则(我们对哪种数据创建索引)

  • 数据量少的没必要创建,全表和用索引可能差不多

  • 表层面:数据量大,且查询频繁,更新不频繁

  • 字段层面:经常在where groupby orderby后的字段

  • 索引层: 唯一的建立唯一索引,尽量联合索引,大文本尽量前缀索引

  • 附加原则:

    • 区分度较高

  • 索引不易过多

  • 索引不为null加上非空约束

  • 索引长度尽量短

索引分类

按结构

按类型

  • 主键索引:唯一且不为null,一个表只能有一个,(聚集索引:叶子节点下存储索引和数据,必须有,且只有一个)

  • 唯一索引:唯一且只能有一个Null值(二级索引,叶子节点存储索引和主键)

  • 普通索引:没有限制(二级索引,叶子节点存储索引和主键)

  • 全文索引:like+%(InnoDB(5.6之后支持)默认3个字符,最大84,MyISam默认4最小1个字符)

按存储形式

聚集索引:必须有,且只有一个,没有会使用唯一索引聚簇,都没有则创建隐藏主键,叶子节点下存放行数据

二级索引:可以多个,叶子节点存放主键id,会回表查询,创建联合索引设计好的话,可避免回表

联合索引

  • 对经常查询的多个字段创建组合索引

sql提示

  • 多个索引下,可以提醒执行器使用哪个索引,建议使用,忽略使用,强制使用

覆盖索引

  • 查询返回字段都在联合索引中会直接拿到数据,无需拿到主键再去回表查询数据

  • 针对字段数据库较大的建立索引,缩小索引长度

单列/联合索引

  • 避免单列索引在and情况下第二索引不生效,使用联合索引

索引失效

  • 索引列进行了函数运算

  • 没有遵循最有匹配原则

  • 字符串类型索引没有加' ',造成隐士转换,导致索引失效

  • 如果联合索引,最左满足,但是使用中间跳过了某个索引字段,会造成后面索引失效

  • 范围查询右侧的列会失效,尽量是<= ,>=

  • mysql优化器判定全表比用索引块

  • or链接索引失效

4、性能分析

数据库的执行频次

- show session status like 'Com_____'; --查询当前会话统计结果
- show global status like 'Com_____'; --查询字数据库上次启动至今的结果
- show status  like 'Innodb_rows_%';

 

慢查询日志

-- 查看慢日志配置信息 
show variables like '%slow_query_log%’; 
​
-- 开启慢日志查询 
set global slow_query_log=1; 
​
-- 查看慢日志记录SQL的最低阈值时间 
show variables like 'long_query_time%’; 
​
-- 修改慢日志记录SQL的最低阈值时间 
set global long_query_time=4;

profile Sql执行查询

explain/desc执行计划查询

  • 字段含义

        

    • id 相同表示加载表的顺序是从上到下。

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

    • id 有相同,也有不同,同时存在。id相同的可以认为是一组,从上往下顺序执行;在所有的组中,id的值越大,优先级越高,越先执行。

  • type含义

  • extra含义

5、锁机制

锁的分类

按粒度分

  • 全局锁:锁定全局,用于数据备份保证数据库完整性

  • 表锁(加锁快,并发低,不会死锁):

    • 表锁:锁定整张表

    • 元数据锁:为了避免DML与DDL冲突,保证读写正确性

    • 意向锁:为了避免加表锁时候,全局扫描行锁

  • 行锁(加锁慢,锁冲突低,并发高,会死锁)

    • 行锁:锁定单行数据

    • 间隙锁:防止其他事务插入间隙,间隙锁可以共存,一个事务间隙锁,不影响另一个事务在同一间隙加锁

      • 索引上等值查询(唯一索引),给不存在的数据加锁时,会优化为间隙锁

      • 索引上等值查询(非唯一索引),向后遍历时最后一个值不满足查询需求时,会退化为间隙锁

    • 临键锁:锁定当前数据和间隙(行锁+间隙锁)

      • 索引上范围查询(唯一索引),会访问到不满足条件的第一个值为止

按类型分

  • 读锁(共享):阻塞写,可读

  • 写锁(排他):阻塞读写

行锁升级

  • 行锁时针对唯一索引进行检索的,对已存在的记录进行等值匹配时,将自动优化为行锁

  • 不通过索引条件检索数据时,行锁则会升级为表锁

6、事务

事务特性

  • 原子性:要么全部成功,要么全部失败

  • 一致性:事务完成后,必须使所有的数据都保持一致状态

  • 隔离性:事务之间互不影响

  • 持久性:事务一旦提交或者回滚,对数据库中的数据改变时永久的

事务隔离级别

  • 读未提交:一个事务可以读取另一个事务未提交的数据(脏读,不可重复读,幻读)

  • 读已提交:可读取另一个事务已经提交的事务(不可重复读,幻读)

  • 可重复读(默认):事务开启时不在允许修改操作,可避免脏读,不可重复读但是会造成(幻读)

  • 串行化:最高事务隔离级别,效率低下

事务原理

  • 原子性:undo_log(逻辑日志),通过回滚日志保证事务原子性,不仅回滚需要,快照读也需要,不会立即删除

  • 持久性:redo_log(物理日志),缓冲区的脏页刷新到磁盘的过程当中出现问题,通过redo_log进行回滚保证数据的持久性,只在回滚时需要,事务结束可被立即删除

  • 一致性:undo_log+redo_log

  • 隔离性:锁+mvcc(多版本并发控制)

MVCC

  • 作用:快照读时候,通过mvcc来查找对应的历史版本

  • 实现组件:

    • 记录隐藏字段(最后一次修改事务id,回滚指针)

    • undo_log版本链(头部最新记录,尾部最老)

    • readView(当前活跃事务id集合,最小活跃事务id,预分配事务id,当前最大事务id+1,readView创建者的事务id)

7、大批量数据插入优化

主键顺序插入

批量插入减少IO,批量最好500左右

load加载数据至数据结构

-- 1、首先,检查一个全局系统变量 'local_infile' 的状态, 如果得到如下显示 Value=OFF,则说明这是不可用的
show global variables like 'local_infile';
 
-- 2、修改local_infile值为on,开启local_infile
set global local_infile=1;
 
-- 3、加载数据 
/*
脚本文件介绍 :
    sql1.log  ----> 主键有序
    sql2.log  ----> 主键无序
*/
load data local infile 'D:\\sql_data\\sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n';

关闭唯一性校验,加载后再打开

-- 关闭唯一性校验
SET UNIQUE_CHECKS=0;
 
truncate table tb_user;
load data local infile 'D:\\sql_data\\sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n';
 
SET UNIQUE_CHECKS=1;

减少事务,批量执行数据

 

posted @ 2022-03-08 15:26  赶星而至  阅读(308)  评论(0编辑  收藏  举报