本文仅限于innodb存储引擎
Created: Apr 13, 2021 7:12 PMCreated By: crazy
Last Edited By: crazy
Last Edited Time: Apr 13, 2021 7:47 PM
本文分3个部分:
1,MySQL的介绍和优化
2,Golang连接MySQL的连接池源码剖析
3,Innodb的索引介绍
什么是MySQL?
MySQL是一种关系型数据库管理系统
磁盘数据是怎么读取的?
在介绍MySQL之前,先简单说说磁盘是怎么读取数据的
MySQL架构
一共分为4层
1,连接层
2,核心服务层:SQL解析,SQL优化等
3,存储引擎层:innodb
4,数据存储层:磁盘
SQL查询过程
只有了解了MySQL的实现原理,才能知道如何着手进行优化
优化阶段
MySQL一共可以从以下3个方向进行优化
1,SQL语句
2,MySQL配置
3,磁盘性能
SQL
SQL自身
例如:like 、 select *、 limit 、join 等
索引
1,单独加索引
2,explain sql 定位
建表:
主键设立:单机用自增id,分布式用专门的发号器或者雪花算法获取分布式id,为什么不用uuid做主键,原因跟数据的落盘,以及磁盘的读取方式有关;
磁盘的数据是怎么读取的呢? 磁头会在磁盘页上顺序的读取,而,innodb是顺序存储的,但是由于uuid是分布,所以在磁盘上为零散的,并不是顺序落盘,这就导致读取效率的降低。
一般遵循3范式,但是如果是clickhouse,那么一般以宽表为主,数仓的建设都是以宽表为主,更利于查询
索引查询
主键查询和普通索引查询也是不一样的
1,主键为聚簇索引,一次查询就能够获取到记录
2,普通索引也为二级索引,非聚簇索引,需要2次:第一次,先查询着id,再根据id查询到对于的数据,相当于二级索引指向主键,该行为称之为回表
3,覆盖索引为特殊的普通索引,不用回表,因为通过组合索引的特性直接获取到对于的数据,explain 的extra中表现为use indexing
MySQL的配置
通过优化mysql自身配置也能实现mysql的优化,具体可以从查询过程中查看,例如:缓存的大小等
磁盘的配置
每次磁盘的读取都是一次机械性的io动作,所以,磁盘读取的快慢直接影响了mysql读取的性能
Golang的MySQL 连接池源码剖析
Golang官方库的介绍
这里明确说明了sql.Open 不会产生新的连接,让我们来看看为什么
db 是sql包里的一个struct
真正发生连接是在每次去执行语句的时候,例如,query
当你执行的时候,他会去判断,如果有空闲的连接,那么就优先用这个空闲的连接,如果没有则新建一个
这里,sql 内部自己维护了一个pool,pool的维护需要考虑几个方面:
- pool的容量大小,不可能无限大,也不可能无限小
- pool的申请和回收,不回收你这个pool 或许一下就被apply完了
最后,可能有的小伙伴会疑惑,那既然sql.Open不是新建一个conn,为什么要db.Close()呢?
那,我们就来一探究竟
从包里的解释,我们能够大致了解到
- 关闭db 这个聚柄
- 连接的处理
- 防止后续有新的conn 链接
- 等待所有进行中的
让我们一起看看源码的真面目
1.保持原子性
2.关闭 conn(chan)
3.db.stop() ,什么是stop(),他是一个context 的cancal(),在sql.Open()的时候定义的
sql.Open()的时候,OpenDB()会定义好context,这个也行就是golang的魅力吧
索引的真面目
本文转载自: 掘金