MySQL底层原理剖析 什么是MySQL? 磁盘数据是怎么读

本文仅限于innodb存储引擎
Created: Apr 13, 2021 7:12 PM

Created 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之前,先简单说说磁盘是怎么读取数据的

Untitled.png

MySQL架构

一共分为4层

1,连接层

2,核心服务层:SQL解析,SQL优化等

3,存储引擎层:innodb

4,数据存储层:磁盘

Untitled 1.png

SQL查询过程

Untitled 2.png

只有了解了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

Untitled 3.png

MySQL的配置

通过优化mysql自身配置也能实现mysql的优化,具体可以从查询过程中查看,例如:缓存的大小等

磁盘的配置

每次磁盘的读取都是一次机械性的io动作,所以,磁盘读取的快慢直接影响了mysql读取的性能

Golang的MySQL 连接池源码剖析

Golang官方库的介绍

这里明确说明了sql.Open 不会产生新的连接,让我们来看看为什么

image.png

db 是sql包里的一个struct

image.png

真正发生连接是在每次去执行语句的时候,例如,query

当你执行的时候,他会去判断,如果有空闲的连接,那么就优先用这个空闲的连接,如果没有则新建一个

image.png

这里,sql 内部自己维护了一个pool,pool的维护需要考虑几个方面:

  1. pool的容量大小,不可能无限大,也不可能无限小
  2. pool的申请和回收,不回收你这个pool 或许一下就被apply完了

最后,可能有的小伙伴会疑惑,那既然sql.Open不是新建一个conn,为什么要db.Close()呢?
那,我们就来一探究竟
从包里的解释,我们能够大致了解到

  • 关闭db 这个聚柄
  • 连接的处理
    • 防止后续有新的conn 链接
    • 等待所有进行中的
      image.png

让我们一起看看源码的真面目

1.保持原子性

2.关闭 conn(chan)

3.db.stop() ,什么是stop(),他是一个context 的cancal(),在sql.Open()的时候定义的

image.png

sql.Open()的时候,OpenDB()会定义好context,这个也行就是golang的魅力吧
image.png

索引的真面目

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%