1 配置文件的使用
my.cnf配置文件
/etc/my.cnf:
[root@hadoop103 ~]# cat /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html
[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove the leading "# " to disable binary logging
# Binary logging captures changes between backups and is enabled by
# default. It's default setting is log_bin=binlog
# disable_log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
#
# Remove leading # to revert to previous value for default_authentication_plugin,
# this will increase compatibility with older clients. For background, see:
# https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin
# default-authentication-plugin=mysql_native_password
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
多个选项组配置以后面的配置为更高的优先级
配置文件和命令行启动参数冲突时以命令行参数为主
启动命令与选项组
mysql的命令可以在/usr/bin和/usr/sbin下面查看,不同的命令会读取配置文件中不同的选项组:
- [server]选项组将作用于所有的服务器程序
- [client]选项组将作用于所有的客户端程序
可以在选项组中添加版本,如[mysqld-5.7]
2 逻辑架构
服务端处理客户端请求
MySQL是典型的C/S架构
,服务端程序使用的是mysqld
。实现的效果就是客户端向服务端发送一段文本(SQL语句),服务器端向客户端返回一条文本(处理结果)。
下面展开来看
- MYSQL服务器之外的
客户端程序
连接池
:提供了多个用于客户端与服务器端交互的线程SQL接口
:接收SQL指令,返回查询结果解析器
:语法、语义解析,生成解析树优化器
:核心组件,对SQL进行优化(是否使用索引、外连接转化。。。)查询缓存
:以key-value方式缓存查询结果(相同的SQL语句直接命中返回)插件式的存储引擎
:与文件系统进行交互,即内存与磁盘的交互文件系统
:即底层的sql文件以及日志文件
connectors
第一层:连接层
系统(客户端)首先经过三次握手
与MYSQL服务器建立TCP连接
,然后MySQL服务器对客户端传来的账户、密码做身份认证和权限获取。
连接层的连接池设有TCP连接池
来限制连接数,并采用长连接模式
复用TCP连接,来实现一个系统可以和MYSQL服务器建立多个连接,提供了多个用于客户端与服务器端交互的线程实现一个服务器也能和多个系统建立连接。
第二层:服务层
-
SQL接口
:接收SQL指令,返回查询结果 -
解析器
:语法、语义解析,生成解析树检查语法错误 -
优化器
:核心组件,对SQL进行优化(是否使用索引、外连接转化。。。) -
查询缓存
:以key-value方式缓存查询结果(相同的SQL语句直接命中返回)
第三层:引擎层
存储层
3 SQL执行流程
1 查询缓存
- Mysql服务器如果在缓存中查到了相同的SQL语句,就会直接将结果返回给客户端;如果没有则进入解析器阶段。
- 之前执行的语句及其结果会以Key-Value的形式存储在内存中。
- 查询缓存往往效率不高,因此在MySQL8.0之后就移除了这个功能。
为什么8.0移除了这个功能?
- 缓存的命中率不高,Mysql中缓存的是查询结果而不是查询计划,只有完全相同的查询才会命中查询缓存,任何字符上的不同(空格、注释、大小写)都会导致缓存不命中
- 一些系统函数、系统表和用户自定义的函数、变量不会被缓存
- 缓存系统会监测涉及到的每一张表,当表的结构、数据被修改,所有使用该表的查询缓存都会被删除,维护消耗了一定的性能和资源
系统变量query_cache_type
在5.0中,query_cache_type有三个值:
- 0代表关闭OFF
- 1代表开启ON
- 2代表按需开启DEMAND
mysql> show VARIABLES like 'query_cache_type';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| query_cache_type | OFF |
+------------------+-------+
1 row in set (0.00 sec)
按需开启的时候,查询的时候添加 SQL_CACHE 使用缓存,SQL_NO_CACHE则不会对SQL使用缓存
QCACHE%查看缓存命中情况
mysql> show status like 'QCACHE%';
+-------------------------+---------+
| Variable_name | Value |
+-------------------------+---------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 1031832 |
| Qcache_hits | 0 |
| Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 2 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 1 |
+-------------------------+---------+
8 rows in set (0.00 sec)
2 解析器
如果没有命中查询缓存,就会进入解析器进行sql语句的分析了,sql语句分析分为两部分:
- 词法分析:识别sql语句中的关键字、表明、列名等信息
- 语法分析:根据语法规则,判断sql语句是否满足sql语法
如果sql语句正确,则会生成一棵语法树
3 优化器
优化器负责确定sql的执行路径即最好的执行计划,以减少查询消耗,比如:
- 是使用
全文检索
还是索引检索
等。 - 在表中有多个索引的时候,是使用哪个索引
- 语句有多表关联,决定表的顺序
- 表达式简化、子查询转化为连接、外连接转换为内连接
- ...
优化又可以分为物理优化和逻辑优化:
物理优化
:通过索引和表连接技术进行的优化逻辑优化
:通过SQL等价变换提高效率(换一种查询写法)
4 执行器
-
在执行之前需要判断用户是否具备权限,如果不具备则返回
权限错误
,否则执行SQL查询返回查询结果。 -
如果设置了查询缓存,就会将查询结果进行缓存。
-
执行SQL查询的时候,首先打开查询的表,根据表的存储引擎定义,调用相应存储引擎API对表进行读写,存储引擎api只是一个抽象接口,下面还有一个
存储引擎层
。
4 MySQL8中的sql执行原理
首先需要开启profiling
profiling可以让Mysql收集在sql执行过程中所使用的资源情况,1表示开启。
mysql> select @@profiling
-> ;
+-------------+
| @@profiling |
+-------------+
| 0 |
+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
show profiles 查看最近执行的sql语句的执行开销
mysql> show profiles;
+----------+------------+-------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------+
| 1 | 0.00016525 | select @@profiling |
| 2 | 0.00030450 | select * from employees |
| 3 | 0.00030550 | select * from employees |
+----------+------------+-------------------------+
3 rows in set, 1 warning (0.00 sec)
show profile for query [num]
mysql> show profile for query 2;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000043 |
| checking permissions | 0.000006 |
| Opening tables | 0.000014 |
| init | 0.000035 |
| System lock | 0.000009 |
| optimizing | 0.000002 |
| statistics | 0.000008 |
| preparing | 0.000007 |
| executing | 0.000002 |
| Sending data | 0.000133 |
| end | 0.000005 |
| query end | 0.000005 |
| closing tables | 0.000004 |
| freeing items | 0.000024 |
| cleaning up | 0.000010 |
+----------------------+----------+
15 rows in set, 1 warning (0.00 sec)