MySQL高级

本文深入探讨了MySQL的高级特性,包括架构、性能监控、数据类型优化、查询优化、索引策略、服务器参数设置等内容。重点分析了连接器、查询缓存、分析器、优化器、Redo和Binlog日志、数据更新流程、性能监控工具如`show profiles`和`performance_schema`。同时,讨论了数据类型选择、索引优化、主键和聚簇索引、分区表等数据库设计原则,以及如何通过调整服务器参数提升MySQL性能。
摘要由CSDN通过智能技术生成

MySQL version:5.7.20

一、MySQL架构

(一)Mysql的基本架构图

Mysql的基本架构图

(二)连接器

连接器

(三)查询缓存

查询缓存

(四)分析器

分析器

(五)优化器

优化器

(六)Redo日志—innodb存储引擎的日志文件

redo日志属于InnoDB存储引擎层面的日志,用来记录事务对缓存页记录的改动,刷盘前改动数据放在redo日志文件中,刷盘后会删除掉,其主要是用来做崩溃恢复,以此来保证事务的持久性;可以通过参数的形式来控制redo日志文件的个数和大小,每个redo日志文件都有自己对应的编号;而binlog日志属于MySQL的server层面的日志,它是以追加的方式把对数据库数据的增删改逻辑操作保存起来,主要用于数据同步或主从复制。
往redo日志和binlog日志中写入数据是一个顺序I/O过程,效率比较高,因为它们是按顺序写入文件的。
redo日志

(七)疑惑

既然要避免io,为什么写redo log的时候不会造成io的问题?
写redo日志时不会造成IO问题的原因是:InnoDB存储引擎会向操作系统申请一个专门的内存空间(buffer pool)用来存放redo日志数据,当达到刷盘条件时一次性刷盘,以此来减轻IO压力

(八)Undo日志

Undo日志

(九)binlog-服务端的日志文件

1.binlog日志与redo日志的区别

binlog日志与redo日志的区别

2.binlog日志

binlog日志

(十)数据更新的流程

数据更新的流程

(十一)Redo log的两阶段提交

Redo log的两阶段提交

二、MySQL性能监控

(一)show profiles工具

show progiles工具是MySQL提供的用来分析SQL执行过程中资源消耗情况的工具,可用于SQL调优的测量,在当前会话中,默认情况下show profiles是处于关闭状态,打开之后默认保存最近15次的运行结果。针对运行慢的SQL,通过profiles工具进行详细分析,可以得到SQL运行过程中的资源开销情况,如IO开销、CPU开销、内存开销等。
show profiles工具的使用
show profile工具的使用

1.官网show profile命令的使用

show profile命令的使用
如何找到show profile命令使用指导模块:
MySQL 5.7 Reference Manual->SQL Statements->Database Administration Statements->
SHOW Statements->SHOW PROFILE Statement
show profile命令使用指导
各种type类型代表的含义

2.show profile cpu;

CPU使用情况

3.show profile all;

查看所有指标项的资源使用情况

(二)performance_schema

1.performance_schema替代show profile和show profiles

高版本MySQL中show profile和show profiles被performance_schema替代掉。show profile和show profiles比performance_schema好用,因为它的功能不是很完善且实现比较简单。
show profile和show profiles将会在高版本MySQL中被弃用

(1)性能监控数据库performance_schema

performance_schema
MySQL数据库会默认自带存放性能监控相关的数据的数据库,其中包含87张表
默认情况下performance_schema性能监控功能是开启的,如果需要关闭该性能监控功能则需要再my.cnf文件修改开关。它不能通过命令方式将其关闭

2.performance_schema详解

见附件:MySQL的performance_schema详解.md

(三)show processlist

1.实时监控MySQL的连接个数

查看实时监控的MySQL连接个数,当使用quit命令退出连接时,连接列表中将不再显示已退出的连接

(1)数据库连接池

一般情况下公司里面都会使用数据库连接池来管理数据库连接。

①dbcp:现在已经很少使用
②c3p0:
③druid:性能较好,目前大多数公司使用

github上开源的druid连接池使用资料

2.官网show processlist命令的使用

(1)官网show processlist命令链接
(2)官网show processlist命令路径:

MySQL 5.7 Reference Manual->SQL Statements->Database Administration Statements->
SHOW Statements->SHOW PROCESSLIST Statement

三、schema与数据类型优化

(一)数据类型的优化

1.更小的通常更好

在psn和psn2表中各插入2w条数据,然后对比.ibd数据文件大小:
应该尽量使用可以正确存储数据的最小数据类型,更小的数据类型通常更快,因为它们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期更少,但是要确保没有低估需要存储的值的范围,如果无法确认哪个数据类型,就选择你认为不会超过范围的最小类型
案例:
设计两张表,设计不同的数据类型,查看表的容量。

CREATE TABLE `psn` (
  `id` int(10) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `psn2` (
  `id` int(10) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
public class Test {
   
    public static void main(String[] args) throws Exception{
   
        long start = System.currentTimeMillis();
        System.out.println("start: "+start);
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/lianpengju?useSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8","root","123456");
        PreparedStatement pstmt = conn.prepareStatement("insert into psn2 values(?,?)");
        for (int i = 0; i < 20000; i++) {
   
            pstmt.setInt(1,i);
            pstmt.setString(2,i+"");
            pstmt.addBatch();
        }
        pstmt.executeBatch();
        long end = System.currentTimeMillis();
        System.out.println("end: "+end);
        System.out.println("用时: "+(end-start)/1000+"s");
        conn.close();
    }
}

2.简单就好

简单数据类型的操作通常需要更少的CPU周期,例如,
1、整型比字符操作代价更低,因为字符集和校对规则是字符比较比整型比较更复杂,
2、使用mysql自建类型而不是字符串来存储日期和时间
3、用整型存储IP地址
案例:
创建两张相同的表,改变日期的数据类型,查看SQL语句执行的速度

CREATE TABLE `emp` (
  `EMPNO` int(4) NOT NULL,
  `ENAME` varchar(10) DEFAULT NULL,
  `JOB` varchar(9) DEFAULT NULL,
  `MGR` int(4) DEFAULT NULL,
  `HIREDATE` date DEFAULT NULL,
  `SAL` double(7,2) DEFAULT NULL,
  `COMM` double(7,2) DEFAULT NULL,
  `DEPTNO` int(4) DEFAULT NULL,
  PRIMARY KEY (`EMPNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `emp2` (
  `EMPNO` int(4) NOT NULL,
  `ENAME` varchar(10) DEFAULT NULL,
  `JOB` varchar(9) DEFAULT NULL,
  `MGR` int(4) DEFAULT NULL,
  `HIREDATE` varchar(255) DEFAULT NULL,
  `SAL` double(7,2) DEFAULT NULL,
  `COMM` double(7,2) DEFAULT NULL,
  `DEPTNO` int(4) DEFAULT NULL,
  PRIMARY KEY (`EMPNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

仅字段类型不同,查询出来的时间却不同
适当的数据类型还可以节省转化开销

3.尽量避免null值

为了避免给后续带来麻烦,尽量避免将字段设置成可为null。另外,字段的默认值慎重设置,因为有可能默认值会出现在业务数据中,会产生干扰。不过,将字符类型的字段默认值设置成空字符还是可以的。
如果查询中包含可为NULL的列,对mysql来说很难优化,因为可为null的列使得索引、索引统计和值比较都更加复杂,坦白来说,通常情况下null的列改为not null带来的性能提升比较小,所有没有必要将所有的表的schema进行修改,但是应该尽量避免设计成可为null的列。

4.实际类型的优化

(1)整型

可以使用的几种整数类型:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT分别使用8,16,24,32,64位存储空间。
尽量使用满足需求的最小数据类型。

(2)字符和字符串类型

1、char长度固定,即每条数据占用等长字节空间;最大长度是255个字符,适合用在身份证号、手机号等定长字符串;
2、varchar可变程度,可以设置最大长度;最大空间是65535个字节,适合用在长度可变的属性;
3、text不设置长度,当不知道属性的最大长度时,适合用text;
按照查询速度:char>varchar>text。

①varchar根据实际内容长度保存数据
1、使用最小的符合需求的长度。
2、varchar(n) n小于等于255使用额外一个字节保存长度,n>255使用额外两个字节保存长度。
3、varchar(5)与varchar(255)保存同样的内容,硬盘存储空间相同,但内存空间占用不同,是指定的大小 。
4、varchar在mysql5.6之前变更长度,或者从255一下变更到255以上时,都会导致锁表。

应用场景
1、存储长度波动较大的数据,如:文章,有的会很短有的会很长
2、字符串很少更新的场景,每次更新后都会重算并使用额外存储空间保存长度
3、适合保存多字节字符,如:汉字,特殊字符等。

②char固定长度的字符串
1、最大长度:255
2、会自动删除末尾的空格

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值