MySQL优化专题

MySQL优化

  • 一、SQL执行过程
    • 通信方式
    • 缓存
  • 二、常用命令
    • 查看连接数
    • 最大连接数
    • 查看当前连接状态
  • 三、查询优化器的模块(Optimizer)
  • 四、存储引擎
    • MyISAM(三个文件)
    • InnoDB(两个文件)
    • Memory (一个文件)
    • csv (三个文件)
  • 五、InnoDB 缓冲池(Buffer Pool)
    • Buffer Pool
    • Change Buffer
    • ( redo )Log buffer
  • 六、InnoDB索引
    • 索引三大类型
    • 索引扩展补充
    • 索引创建
    • 索引失效情况
    • InnoDB存储结构

一、SQL执行过程

MySQL优化专题_第1张图片

通信方式

MySQL使用半双工方式工作,要么客户端向服务端发送数据,要么服务端向客户端发送数据,并且在一次连接中数据是不能分成小块发送的,不管你的 SQL 语句有多大,都是一次性发送。
如存在数据量过大情况,调整此max_allowed_packet参数。同时尽量避免无limit查询操作。

  • 单工:在两台计算机通信的时候,数据的传输是单向的。生活中的类比:遥控器。
  • 半双工:在两台计算机之间,数据传输是双向的,但在这个通讯连接里面,同一时间只能有一台服务器在发送数据,一个发完另一个才能发。生活中的类比:对讲机。
  • 全双工:数据的传输是双向的,并且可以同时传输。生活中的类比:打电话。

缓存

默认关闭 show variables like ‘query_cache%’; 不推荐使用,8.0之后已被移除。

二、常用命令

show 的参数说明:
1、级别:会话 session 级别(默认);全局 global 级别
2、动态修改:set,重启后失效;永久生效,修改配置文件/etc/my.cnf

查看连接数

show global status like ‘Thread%’

  • Threads_cached:缓存中的线程连接数。
  • Threads_connected:当前打开的连接数。
  • Threads_created:为处理连接创建的线程数。
  • Threads_running:非睡眠状态的连接数,通常指并发连接数

最大连接数

  • show variables like ‘max_connections’;
  • set global max_connections = 1000; 设置最大连接数

查看当前连接状态

SHOW PROCESSLIST (root 用户)查看 SQL 的执行状态
常见状态

  • Sleep 线程正在等待客户端,以向它发送一个新语句
  • Query 线程正在执行查询或往客户端发送数据
  • Locked 该查询被其它查询锁定
  • Copying to tmp table on disk
    临时结果集合大于 tmp_table_size。线程把临时表从存储器内部格式改
    变为磁盘模式,以节约存储器
  • Sending data 线程正在为 SELECT 语句处理行,同时正在向客户端发送数据
  • Sorting for group 线程正在进行分类,以满足 GROUP BY 要求
  • Sorting for order 线程正在进行分类,以满足 ORDER BY 要求

三、查询优化器的模块(Optimizer)

查询优化器的目的就是根据解析树生成不同的执行计划(Execution Plan),然后选择一种最优的执行计划,MySQL 里面使用的是基于开销(cost)的优化器,那种执行计划开销最小,就用哪种。

  • show status like ‘Last_query_cost’;查看查询的开销

查看MySQL执行计划

  • EXPLAIN select name from user where id=1;

四、存储引擎

  • 对数据一致性要求比较高,需要事务支持,可以选择 InnoDB。
  • 数据查询多更新少,对查询性能要求比较高,可以选择 MyISAM。
  • 需要一个用于查询的临时表,可以选择 Memory

表级别存储引擎,也称表类型。

  • show engines ; 查看数据库支持的存储引擎
  • show variables like ‘datadir’; 查看数据库数据存放路径
  • show table status from itxw2020; 查看数据库表对应的存储引擎

MyISAM(三个文件)

适用于 只读或读为主的工作。
应用:快速插入百万级数据,先用MyISAM插入后修改存储引擎为InnoDB

  • 支持表级别的锁,插入和更新会锁表。
  • 不支持事务
  • 拥有较高的插入和查询效率
  • 存储了表的行数(count)速度快

InnoDB(两个文件)

适用于 经常更新的表,存在并发读写以及事务处理的业务系统

  • 支持行级别,表级别锁
  • 支持事务,支持外键,数据完整性,一致性更高
  • 支持读写并发
  • 将用户数据存储在聚集索引中,可以减少IO,提高查询效率

Memory (一个文件)

数据存储在内存中,读写速度快,重启会造成数据丢失。

csv (三个文件)

不允许空行,不支持索引。格式通用,可以直接编辑,适合在不同数据库之
间导入导出。

五、InnoDB 缓冲池(Buffer Pool)

InnnoDB 的数据都是放在磁盘上的,InnoDB 操作数据有一个最小的逻辑单
位,叫做页
(索引页和数据页)。InnoDB 使用了一种缓冲池的技术,也就是把磁盘读到的页放到一块内存区域里面。这个内存区域就叫 Buffer Pool。
MySQL优化专题_第2张图片Buffer Pool 主要分为 3 个部分: Buffer Pool、Change Buffer、Adaptive Hash Index,另外还有一个(redo)log buffer

Buffer Pool

Buffer Pool 默认大小是 128M(134217728 字节),可以调整。
查看参数(系统变量):
SHOW VARIABLES like ‘%innodb_buffer_pool%’;

Change Buffer

数据库大部分索引都是非唯一索引,并且业务是写多读少,不会在写数据后立刻读取,就可以使用 Change Buffer(写缓冲)。写多读少的业务,调大这个值:
SHOW VARIABLES LIKE ‘innodb_change_buffer_max_size’;
代表 Change Buffer 占 Buffer Pool 的比例,默认 25%。

( redo )Log buffer

InnoDB 把所有对页面的修改操作专门写入一个日志文件,并且在数据库启动时从这个文件进行恢复操作(实现 crash-safe)——用它来实现事务的持久性,防止数据库宕机带来的数据丢失。
/var/lib/mysql/目录下的ib_logfile0 和 ib_logfile1,每个 48M。

  • 关键点就是先写日志,再写磁盘
  • show variables like ‘innodb_log%’; 查看日志相关参数

六、InnoDB索引

索引三大类型

  • 普通索引(Normal):非唯一索引
  • 唯一索引 要求键值不能重复。主键索引(primary key)是特殊的唯一索引,要求键值不能为空
  • 全文索引 针对较大数据字段(char、varchar、text),解决like查询效率低,也可创建全文索引
    全文索引使用
select * from fulltext_test where match(content) against('模糊值' IN NATURAL LANGUAGE MODE);

索引扩展补充

  • 聚集索引(聚簇索引):索引键值的逻辑顺序跟表数据行的物理存储顺序是一致的。主键索引是聚集索引,非主键都是非聚集索引
  • 主键索引 辅助索引
    辅助索引存储的是辅助索引和主键值。如果使用辅助索引查询,会根据主键值在主键索引中查询,最终取得数据
  • 如果没有主键索引
    1、如果我们定义了主键(PRIMARY KEY),那么 InnoDB 会选择主键作为聚集索引。
    2、如果没有显式定义主键,则 InnoDB 会选择第一个不包含有 NULL 值的唯一索引作为主键索引。
    3、如果也没有这样的唯一索引,则 InnoDB 会选择内置 6 字节长的 ROWID 作为隐藏的聚集索引,它会随着行记录的写入而主键递增。
  • 列的离散度越高,重复记录越少。建立索引应选择离散度跟高的字段。
  • 联合索引最左匹配 建立联合索引,将最常用的列放在左边
    index(a,b,c) 相当于创建了 index(a), index(a,b),index(a,b,c)
  • 覆盖索引
    回表:
    非主键索引,我们先通过索引找到主键索引的键值,再通过主键值查出索引里面没有的数据,它比基于主键索引的查询多扫描了一棵索引树,这个过程就叫回表。
    避免回表:
    在辅助索引里面,不管是单列索引还是联合索引,如果 select 的数据列只用从索引中就能够取得,不必从数据区中读取,这时候使用的索引就叫做覆盖索引,这样就避免了回表
  • 索引条件下推
    索引条件下推(Index Condition Pushdown),5.6 以后完善的功能。只适用于二级索引。ICP 的目标是减少访问表的完整行的读数量从而减少 I/O 操作

索引创建

  • 在where 、order 、join on 字段上创建
  • 离散度低的字段不要建立索引
  • 频繁更新的值不要建立索引或作为主键
  • 组合索引将离散度高的列放在前面
  • 创建复合索引,而不是修改单例索引
  • 索引个数不要多

索引失效情况

用不用索引,最终都是优化器说了算,最小开销决定。

  • 索引列上使用函数(replace\SUBSTR\CONCAT\sum count avg)、表达式、计算(+ - * /)
  • 字符串不加引号,出现隐式转换
  • like 前面带 %
  • 负向查询 not like 。 !=,not in在某些情况下不失效

InnoDB存储结构

B+树(加强版多路平衡查找树)
MySQL优化专题_第3张图片
B+树特点

  • 1、它的关键字的数量是跟路数相等的;
  • 2、B+Tree 的根节点和枝节点中都不会存储数据,只有叶子节点才存储数据。搜索到关键字不会直接返回,会到最后一层的叶子节点。比如我们搜索 id=28,虽然在第一层直接命中了,但是全部的数据在叶子节点上面,所以我还要继续往下索,一直到叶子节点。

MySQL 的存储结构分为 5 级:表空间、段、簇、页、行
MySQL优化专题_第4张图片

补充:红黑树,根节点到叶子节点最长距离(红黑相间)不大于最短路径(全是黑色)的两倍。

你可能感兴趣的:(数据库专题)