对于一个服务端开发来说 MYSQL 可能是他使用最熟悉的数据库工具,然而熟练掌握 MYSQL 语句的拼写和卓越的多条件查询不代表出现性能问题的时候你知道该怎么解决。致力于不当 SQL boby,我们从头开始入门 MYSQL,讲一些你可能不知道的 MYSQL。

1. 一条 SQL 之旅

现在有一条查询用户信息表的 SQL :

select * from user where uid = 100001;

这条 SQL 是如何从你的应用程序到达 MYSQL 服务器并执行,然后查到结果再带给你的呢?要回答这个问题我们的看一下 MYSQL 的整体架构:

建立连接

首先客户端与 MYSQL 服务器建立连接这个就不用说,客户端发起请求经过三次握手之后与服务器建立 TCP 连接;服务器收到请求之后对输入的用户名密码做权限校验, 校验通过之后后续的通信就基于这个长连接进行传输。

一般来说一个 MYSQL 服务端是可以对应多个客户端的,所以在服务端可能会有很多个客户端连接同时保持,可以通过 show processlist; 命令来查看当前服务端有多少个连接:

mysql> show processlist;

+---------+------+---------------------+-------------------+---------+-------+-------+------------------+

| Id | User | Host | db | Command | Time | State | Info |

+---------+------+---------------------+-------------------+---------+-------+-------+------------------+

| 1753984 | test | 10.31.0.64:65264 | xxx | Sleep | 92 | | NULL |

| 6348496 | test | 10.26.134.61:43080 | xxx | Sleep | 2 | | NULL |

| 7201973 | test | 10.26.8.104:61642 | xxx | Sleep | 927 | | NULL |

| 7201976 | test | 10.26.8.104:61650 | xxx | Sleep | 927 | | NULL |

| 7414866 | test | 10.26.134.238:52010 | xxx | Sleep | 32 | | NULL |

......

......

......

+---------+------+---------------------+-------------------+---------+-------+-------+------------------+

42 rows in set (0.00 sec)

上面有个 Time 参数:表示该连接已经多久没有发生过数据传输。默认如果超过 8 小时没有发生过数据传输服务端就会自动关闭该连接。可以通过 wait_timeout参数来设置超时时间。

查询缓存

MySQL 查询缓存是 MySQL 中比较独特的一个缓存区域,用来缓存特定 Query 的整个结果集信息,且共享给所有客户端。为了提高完全相同的 Query 语句的响应速度,MySQL Server 会对查询语句进行 Hash 计算后,把得到的 hash 值与 Query 查询的结果集对应存放在Query Cache 中。当 MySQL Server 打开 Query Cache 之后,MySQL Server 会对接收到的每一个 SELECT 语句通过特定的 Hash 算法计算该 Query 的 Hash 值,然后通过该 hash 值到 Query Cache 中去匹配。

查询缓存相关的配置参数有如下:

mysql> show variables like '%query_cache%';

+------------------------------+---------+

| Variable_name | Value |

+------------------------------+---------+

| have_query_cache | YES | --查询缓存是否可用

| query_cache_limit | 1048576 | --可缓存具体查询结果的最大值

| query_cache_min_res_unit | 4096 | --查询缓存分配的最小块的大小(字节)

| query_cache_size | 599040 | --查询缓存的大小

| query_cache_type | ON | --是否支持查询缓存

| query_cache_wlock_invalidate | OFF | --控制当有写锁加在表上的时候,是否先让该表相关的 Query Cache失效

+------------------------------+---------+

6 rows in set (0.02 sec)

开启缓存

mysql> set global query_cache_size = 600000; --设置缓存内存大小

mysql> set global query_cache_type = ON; --开启查询缓存

关闭缓存

mysql> set global query_cache_size = 0; --设置缓存内存大小为0, 即初始化是不分配缓存内存

mysql> set global query_cache_type = OFF; --关闭查询缓存

分析器

如果查询缓存未开启或者为命中的情况则会走正常的查询流程,第一步就是 sql 解析器,作用是将整个查询语句变为 MYSQL 服务器能理解的语言。

词法分析:将整个查询分解为多个元素;

语法分析:寻找 sql 语法规则产生一个序列并执行这些代码;

已经前两步之后会产生一个解析树,提供给优化器使用。

查询优化器

优化器工作主要包括两个部分:

逻辑优化;

物理优化。

逻辑优化阶段:大牛们为了我们这些渣渣程序员操碎了心,怕你写的 sql 不好查询慢然后上网发帖 “MYSQL 垃圾”,“再也不用 MYSQL,我准备自己写个数据库”,于是默默在在后台给你整了个 sql 语句优化。优化内容主要有:

一定能带来优化效果的:

连接的消除(外连接,嵌套连接)

语义优化

冗余操作剪枝

可能会带来性能的提升但是需要根据代价进行选择

借用索引来优化分组、排序等操作

合并分组

连接查询条件下推

公式条件的提取

谓词上推

物理优化阶段: 逻辑优化主要是针对语法规则和语义的规整、合并、裁剪,那么到了物理优化阶段就需要拿着 MYSQL 认为是比较完美的 sql 去查询底层存储单元。查询物理存储需要解决的问题包括:

单表扫描中什么样的方式扫描效率最优

两个表连接的时候如何 join 才能最快的获取数据

多表连接的时候如何进行排序,是否要对每种组合都进行探索

早期物理优化阶段使用基于关系代数规则和启发式规则对查询进行优化后就认为生辰的执行计划是最优的。后面引入了最小代价查询方式对每一个可能的可执行方式进行评估找到代价最小的作为最优执行计划,目前数据库的查询通常是将这两种方式融合到一起。

关于优化器部分是可以讲上几天都讲不完的,在此我们只是简单介绍。

执行器

经过上面阶段已经将如何查询得到数据的最优解拿到,执行器需要做的是根据指令去获取数据。

2. MYSQL 数据存储

MYSQL 作为一个数据库管理工具最底层肯定是将数据存入磁盘的,那么数据是如何进入磁盘的,进入磁盘之后的格式是什么,用什么方式来管理这些数据,让我们带着种种疑团走进 “今日说法”,一起来揭开这个秘密。

2.1 存储引擎

根据对数据存储方式、使用方式的要求, MYSQL 提供了各种私人订制方案来让客户爸爸满意,这些技术方案通过使用不同的存储机制、索引方式、锁技巧最终得到不同的组合效果同而适配不同的应用场景,我们将这种组合得到的产物定义为:存储引擎。

存储引擎主要做了哪些事情呢,包括不限于:

用合适的格式存储数据

提供数据查询,更新的接口

各种条件下数据一致性的支持

索引机制的建立

提供数据备份、故障恢复、故障转移的能力

对于上面这些基本要求的实现,MYSQL 提供了哪些方案呢?

MyISAM

ISAM :Indexed Sequential Access Method(有索引的顺序访问方法)。MyISAM 底层基于这个引擎做了一些改良,这是 MYSQL 5.5 版本之前默认数据库引擎,在当时那个年代提供了一些 当时没有但是很必要 的特性:

索引管理

字段管理

表锁

当时这些功能可是没有的,早期的程序员确实很辛苦啊,人家造轮子是真轮子用来跑的,现在造轮子也是轮子不过是站在巨人的肩膀看得更远了吧。

MyISAM 引擎对每张表的存贮会归结为三个文件:

.frm:以表的名字开始,存储表定义;

.MYD:存储表数据;

.MYI:存储表索引。

因为 MyISAM 诞生的年代比较早,那时候也没有现在互联网这么庞大的需求,所以放在现在来看它其实是有很多的缺点,比如:

锁粒度太大,MyISAM 表锁有两种模式:表共享读锁,表独占写锁。读的时候他不会阻塞其他用户对同一表读的需求,但是在读期间不能写;在写的时候,会同时阻塞其他用户对表的读写操作。这个放在现在高并发的场景下肯定是个灾难。

MyISAM 不支持事务。这种锁机制也注定了它不能支持事务,它生来就是为了 select 操作更快而优化的并且也是满足当时时代的场景。

在崩溃恢复方面,因为各种备份机制没有那么多,带来的直接后果就是它不支持崩溃后的安全恢复。

MEMORY

内存表,很显然这种表是为了读取速度而生。它既不支持事务也不支持外键等等,内存表的优势是读取快,那缺点就很多了:

对于 Varchar 类型使用固定大小的长度存储,浪费空间;

占用内存资源,可能会造成内存崩溃;

服务器重启,数据丢失。

InnoDB

从 MYSQL 5.5 开始,InnoDB成为表的默认引擎。它具有有史以来堪称完美的特点:行锁设计、支持多版本隔离控制、支持外键、支持一致性非锁定读、同时对内存和 CPU 的使用也随着新硬件的发展做了一定的优化。

InnoDB 引擎本身是基于磁盘存储数据的,但是因为 CPU速度和磁盘速度之间巨大的差距,所以在 InnoDB 引擎中大量使用缓冲池技术来提高读写速度。整体可以分为两个部分:

缓冲区

缓冲区的类型也是各种各样,主要包括:

Buffer Pool:缓冲池,在主内存中开辟的一个区域,在 InnoDB 读数据的时候会先访问这里,以减少磁盘访问频次;

Change Buffer:写缓冲区,避免每次增删改都进行IO操作;

Adaptive Hash Index:自适应哈希索引,使用索引关键字的前缀构建哈希索引,提升查询速度;

Log Buffer:日志缓冲区,保存要写入磁盘上的日志文件的数据,缓冲区的内容定期刷新到磁盘。

磁盘数据

磁盘中的数据结构可以分为两大类:表空间和重做日志。

表空间又可分为:

The System Tablespace(系统表空间):存储更改缓冲区;

File-Per-Table Tablespaces(独立表空间):存储单个Innodb表的数据和索引;

General Tablespaces(通用表空间):使用CREATE TABLESPACE创建的共享表;

Undo Tablespaces(undo表空间):存储undo日志;

Temporary Tablespaces(临时表空间):临时表包括会话临时表和全局临时表。

重做日志,redo log 保存的就是 buffer pool 刷到磁盘的数据。

InnoDB 在磁盘中对应的文件结构比较多,除去 redo log 和 bin log之外的主要文件有:

.opt:数据库配置文件,包含数据库字符集属性;

.frm:数据表元数据文件,不管是独立表空间还是系统表空间,每个表都对应一个;

.ibd:数据库独立表空间文件,如果是独立表空间则对应一个.ibd文件,否则保存在系统表空间。

后面我们专门找一节来讲 InnoDB 引擎,这里简单概述。

3. 常用命令

那么对于我们使用的数据库如何查看当前使用的引擎呢:

查看当前 MYSQL 版本所支持的引擎:

mysql> show engines;

+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+

| Engine | Support | Comment | Transactions | XA | Savepoints |

+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+

| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |

| CSV | YES | CSV storage engine | NO | NO | NO |

| MyISAM | YES | MyISAM storage engine | NO | NO | NO |

| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |

| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |

| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |

| ARCHIVE | YES | Archive storage engine | NO | NO | NO |

| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |

| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |

+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+

9 rows in set (0.00 sec)

查看 MYSQL 默认的存储引擎:

mysql> show variables like '%storage_engine%';

+----------------------------+--------+

| Variable_name | Value |

+----------------------------+--------+

| default_storage_engine | InnoDB |

| default_tmp_storage_engine | InnoDB |

| storage_engine | InnoDB |

+----------------------------+--------+

3 rows in set (0.01 sec)

查看某个表用了什么引擎(在显示结果里参数engine后面的就表示该表当前用的存储引擎):

mysql> show create table 表名;

修改表的存储引擎:

ALTER TABLE 表名 ENGINE = INNODB;

修改默认存储引擎

如果修改本次会话的默认存储引擎(重启后失效),只对本会话有效,其他会话无效:

mysql> set default_storage_engine=innodb;

Query OK, 0 rows affected (0.00 sec)

修改全局会话默认存储引擎(重启后失效),对所有会话有效:

mysql> set global default_storage_engine=innodb;

Query OK, 0 rows affected (0.00 sec)

希望重启后也有效,即编辑 /etc/my.cnf,[mysqld] 下面任意位置添加配置(所有对配置文件的修改,重启后生效)

default-storage-engine = InnoDB

关于 MYSQL 的结构部分限于篇幅就简单介绍,后面我们一一来看细节。

mysql的set架构_MYSQL 整体架构浅析相关推荐

  1. mysql设置root只读_mysql主从架构的实现

    阅读文本大概需要20分钟. 1.1 环境准备: centos系统服务器2台. 一台用户做Mysql主服务器, 一台用于做Mysql从服务器, 配置好yum源. 防火墙关闭. 各节点时钟服务同步. 各节 ...

  2. mysql别人的框架_MySQL逻辑架构

    1.MySQL实现步骤 MySQL实现中分为三个步骤,1).客户端.2).server端.3).引擎端. 2.server端 server端分为连接器.查询缓存.分析器.优化器.执行器. 3.引擎端 ...

  3. mysql系统的功能_MySQL系统架构及功能概述

    1 MySql与传统数据的区别在于存储引擎架构.MySql是三层架构,最上层是连接层,包括安全认证.授权等功能:中间是服务层,大多数功能在这一层实现,包括存储过程.触发器.视图,这一层包含了其核心服务 ...

  4. 讲mysql执行流程书籍_MySQL 基础架构 1. 一条SQL查询语句的执行过程(个人学习笔记)...

    MySQL的逻辑架构图: MySQL 大体分为 "server 层" 和 "存储引擎层" 两部分: Server 层 包括 连接器.查询缓存.分析器.优化器.执 ...

  5. mysql获取逻辑日志_Mysql 逻辑架构图及日志系统

    1.Mysql逻辑架构图 场景一:一条SQL语句如何执行? 如图显示一条SQL语句的执行过程: 执行器的执行流程: 2.Mysql日志系统 说到日志系统,需要了解几个概念:creash-safe.re ...

  6. mysql的相关技术说明_MySQL 系统架构 说明

    说明:本文转自 简朝阳(MySQL ACE)的 <MySQL性能调优与架构设计> 一.逻辑模块组成 总的来说,MySQL 可以看成是二层架构,第一层我们通常叫做SQL Layer,在MyS ...

  7. mysql设计架构_MySQL设计架构

    在应用Impala这种所谓大年夜数据引擎的时刻,总会感到有些处所设计的不是那么精细绝伦,比如说缓存,Impala的萌芽结不雅是没有经由缓存的,也就是说每次都相当于须要从新对文件履行一遍萌芽. MySQ ...

  8. 【车载以太网】【架构】整体架构与协议标准

    一.车载以太网架构图 二.通讯相关协议介绍 应用层:DHCP /SOMEIP/DoIP/XCP/UDPNM 传输层:TCP/IP 网络层:IPv4/IPv6/ARP/ICMP 链路层:IEEE Eth ...

  9. mysql in优化_MySQL 探秘: 1 整体架构

    新开坑,计划做一系列专辑.由于 MySQL 源码太庞大,不可能面面俱到,先从丁奇<MySQL 实战 45 讲>[1] 案例开始入手,case by case 来做分享.同时强烈推荐丁奇的课 ...

最新文章

  1. 解决pytorch-gpu 安装失败方案
  2. C#反射实例No.1
  3. 做向量召回 All You Need is 双塔
  4. 从抛硬币试验看随机游走定义的基本概念错误
  5. 汽车金融平台百金贷宣布良性退出网贷业务
  6. win11正式版iso镜像如何安装 windows11正式版iso镜像安装方法
  7. 浅谈局部敏感哈希LSH
  8. JVM虚拟机详解(一)JVM与JAVA体系统结构
  9. 双线性函数matlab,双线性插值(Matlab实现)
  10. 构建WebIM聊天程序
  11. Android项目中使用XUI框架的准备工作
  12. Kotlin学习资料
  13. vm8网卡原理及应用
  14. uniapp:小程序对接腾讯云语音视频通话,简单demo
  15. WINVNC Server详解
  16. 苹果MACOS电脑MAC地址修改的方法
  17. JS点击复制按钮复制相关内容
  18. vivo计算机的隐藏功能介绍,六大vivo隐藏黑科技功能 绝对有你不知道的
  19. ByteBuffer常用方法与分析
  20. 你好, View Binding! 再次再见, findViewById!

热门文章

  1. python随机生成k个不重复的随机数_使用Python生成不重复的随机值
  2. 2017.10.10 取石子游戏 失败总结
  3. 2017.9.10 土地购买 思考记录
  4. c语言block内部的实现原理,iOS中block变量捕获原理详析
  5. 【英语学习】【WOTD】sentient 释义/词源/示例
  6. 五 .3D-2D:PnP问题求解 非线性法BA
  7. fastjson的一些常见用法
  8. 编译时如何看到每个文件的编译选项_导出 Clang 可视化编译耗时分析报告 —— ftimetrace 的使用...
  9. java下载网页所有图片_java 下载网页,图片 | 学步园
  10. 阿里巴巴证实全资收购协作软件平台 Teambition