MySql数据库优化及SQL优化

MySql数据库优化及SQL优化

MYSQL简介


MySQL是一个关系型数据库管理系统,由瑞典MySql AB公司开发,这个公司被SUN公司收购后,SUN又被Oracle收购了,所以,目前MySql属于Oracle公司,是的,你没看错,就是那个有Oracle数据库的Oracle公司.
MySql所使用的Sql语句是用于访问数据库的最标准语言,MySql采用了双授权的方式,分为社区版和商业版,由于其体积小,速度快,总体拥有成本低,尤其是开放源码这一特点,一般中小型企业的开发都选择MySql作为网络数据库.

现在很多站采用的是LAMP架构:

L : Linux     操作系统    A : Apache    web服务器    M : MySql     数据库    P : Php       数据操作
特色:
基于文件存储
单线程多进程
插件式的存储引擎

MySql的整体架构图:

在这里插入图片描述
由上图可以看出,MySQL的优化方向有很多,每个部分都可以是优化的点:

操作系统层面的优化    
文件层的优化    
网络层的优化    
存储引擎的优化    
索引的优化    
事务的优化    
...

MySql的架构:

文件系统层:        MySql数据库中的表,库都是以文件的形式存在磁盘上的,数据库的事物,隔离等也都是以日志的形式存储和使用的.
存储引擎层:    常用的引擎有MyISAM,InnoDB(默认)等,根据不同的场景使用你不同的存储引擎,InnoDB支持ACID的完整事务,以及第三档的可重复读的隔离级别;
SQL接口层:        数据库管理语言,数据定义语言,存储过程,视图,触发器等等,以及数据的增删改查等
解析图:        
优化访问路径 :        
缓存和缓冲池全局和具体引擎的缓存和缓存池 :     比如 InnoDB 在内存,磁盘有不同的缓存位置
MySql接口层:    mysql对外提供一个Tcp接口,不同用户通过Mysql提供的tcp访问接口访问MYSql服务.

Mysql数据库属于单进程多线程的数据库,不同于redis的单进程单线程,在多线程的时候容易出现错误,所以,需要事务的辅助.

MYSQL的引擎:

引擎名 介绍
MYISAM MySql 5.0 之前的默认存储引擎,最为常用,具有较高的插入,查询速度,但是不支持事务,表级锁
InnoDB Innodb是事务型数据库首选引擎,支持ACID,支持行级锁定,MySQL5.5之后成为默认数据库引擎
BDB BDB源自 berkeley DB,事务型数据库的另一种选择,支持commit,rollback等其他事务
Memory Memory所有数据置于内存,拥有极高的插入,更新和查询效率,但是会占用和数据量成正比的内存空间,并且容器在数据库重启的时候丢失数据
Merge Merge是将一定数量的MyISAM表联合在一起成为一个整体,在超大规模数据库存储时很有用.
Archive Archive非常适合存储大量历史,很少被操作的数据,因为他们不经常被使用,Archive拥有高效的插入速度,但对其查询的支持比较差
Federated Federated 将不同的mysql服务器联合起来,组成一个整体,非常适合分布式应用.
cluster/ndb cluster/ndb 高冗余的存储引擎,联合多态数据机器提供服务以提高性能和安全性,非常适合数据量大,安全和性能要求高的应用.
blackHole 黑洞引擎,写入的任何数据库都会消失,一般用于记录Binlog做复制的中继.

ACID事务:

A : 原子性  
B : 一致性  
C : 隔离性 通过加锁的方式效率太差,所以mysql可以通过其他方式来保证隔离的情况下提高并发效率,例如: mysql常用MVCC(多版本并发控制)     
        MVCC:     多版本并发控制技术,它使用大部分支持行锁的事物引擎,不在单纯的使用行锁来进行数据库的并发控制,    取而代之的是把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库的并发性能.  
D : 持久性 
研究数据库的方向有三个: 事务,索引,水平拓展

MyISAM 和 InnoDB引擎的区别:

MyISAM InnoDB
不支持事务,回滚将会造成不完全回滚,不具有原子性 支持事务处理
不支持外键 支持外键
表级锁 行级锁
支持全文索引(fulltext) 支持全文索引(fulltext) 5.6+
保存表的具体行数,不带where时,直接返回保存的行数 不保存表的行数,扫描表来计算有所少行
delete表时,先drop表,然后重建表 delete表时,是一行一行的删除
MYISAM表被存放在三个文件,.frm文件存放表格定义,数据文件是MYD(mydata),索引文件是MYI(myindex) innodb把数据和索引存放在表空间里面,表定义在.frm文件中,表数据和索引则放在.idb文件
跨平台很难直接拷贝使用 跨平台可以直接拷贝使用
MyisamZ中可以使用auto_increment类型字段建立联合索引 Innodb中必须包含auto_increment类型字段的索引
表格可以被压缩 表格很难被压缩
sql的优化主要是存储引擎的优化

MySql索引底层结构简介


索引的本质:

mysql官方对索引的定义是: 索引是帮助mysql高效获取数据的数据结构
而数据结构的核心是:

        时间复杂度
        空间复杂度

常用的实现索引的数据结构:

B+tree索引:

       几乎所有的存储引擎,存储服务器都使用了b+tree,而不是使用二叉树,是因为B+Tree所有的子叶节点都在最后一层,这样树高就降低了,时间复杂度就降低了,通过优化数据结构,空间复杂度也就降低了.
       一些基本类型如日期型,段字符串型也是通过b+tree来实现索引.

b+tree如下图所示:
在这里插入图片描述
非叶子节点存储关键字,叶子节点存储数据,并且所有叶子节点都存在最后一层.

B-Tree 与 B+Tree 的区别:

B-Tree:
使用B-Tree数据结构来存储数据,每个节点由指针+key+date的结构来存储,指查找下一个节点的指针,而且,同一层的键值对是按照顺序排列的.每个字节点到根节点的距离相同.

如下图所示:
在这里插入图片描述

特点:
1 . 是多叉树,而不是二叉树
2 . 节点的组成 指针+数据(key+value)
3 . 所有的节点都是有序的
4 . 所有页节点都在同一层

B+Tree:
同b-tree数比较:
B+Tree树每个节点的指针数是2d而不是2d+1
内节点不存data,只存key,叶子节点不存指针
每个叶子几点有个指向下一个节点的指针,形成了带有顺序的叶子节点

叶子指针添加指向下一个节点的指针的作用是提高查询效率,当进行范围查询的时候,只用添加两把行级锁而不用每行记录都添加一把锁了.

如下图所示:
在这里插入图片描述

HASH索引:

hash又被称为散列表,存储的值通过散列算法计算出一个地址,然后存储,查找的时候相反
如下图所示 :
公式类似于 m % n = address
在这里插入图片描述

理想状态下:
时间复杂度和空间复杂度可能是m,也可能是n,
当输入的值经过散列计算后,如果冲突了,会进行再散列,再散列的方式可能是链式散列,也可能是二次散列,在这种情况下,时间复杂度和空间复杂度都会发生变化,时间负责度增高,空间复杂度看情况.

使用场景:
缓存,小数据库量数据,冲突小的数据

R-Tree索引:

r-tree索引在新版本中才有,用于存储空间数据,三维数据等
比如: 地理位置,经纬度,二维或三维信息.

Full-Text索引:

大文本类型 , 使用全文索引

步骤:
对输入的大文本分词,分的每个词都反向关联大文本,形成一种倒排表的形式,当搜索输入关键词,对这个词进行匹配,然后找到对应的大文本返回.用于取代like在大文本时效率差的情况.

如下图所示:
在这里插入图片描述

sql的优化本质上是索引的优化

MySql Explain执行计划详解

所谓执行计划,就是查看sql语句在执行过程中的执行顺序,是否使用索引,以及使用的索引信息等

基本语法:

  1. explain 要执行的sql语句: 查询计划的基本语法
    例如 : explain select * from ‘table_name’
    结果如下图所示:
    在这里插入图片描述

  2. explain extended 要执行的sql语句: 将表格形式的执行计划转变成sql语句,在使用show warning 后可以显示优化后的语句
    例如 : explain extended select * from ‘table_name’

  3. explain partitions 要执行的sql语句: 用于分区表的explain
    例如 : explain partitions select * from ‘table_name’

执行计划字段详解:

id

id 对应的是执行顺序,如果相同,执行顺序从上到下

id 不同的时候,id大的先执行

id 为null的时候表示是一个结果集,不需要进行查询,常出现在包括union等语句中

select_type 查询类型
id select_type 描述
1 simple 不包含任何子查询和union查询
2 primary 包含子查询最外层查询就显示primary
3 subquery 在select或where中包含的子查询
4 dervided from语句中包含的子查询
5 union 出现在union后的查询语句中
6 dependet union 从union语句中获取结果集
tyep 访问类型
id type 描述
1 system const的特例,当前表上只有一条记录匹配
2 const 使用主键或唯一索引查询,且结果只有一条记录匹配
3 eq_ref 在join语句中使用主键或union not null 索引关联
4 ref 使用非唯一索引查询
5 fulltext 使用全文索引查询
6 ref_or_null 对null 进行索引优化的ref
7 unique_subquery 在子查询中使用eq_ref
8 index_subquery 在子查询中使用ref
9 range 索引范围查找
10 index 覆盖索引,索引作扫描,是基于索引在索引的叶子节点上找满足条件的数据(不需要访问数据文件)
11 all 扫描全表数据
这里面序号越大效果越不好
possible_key

可能使用的索引,注意这里是可能,不一定使用,查询中如果涉及到的字段上有索引,则该索引会被列出来

  • 注意: 当该列为null 的时候就要考虑当前的sql是否需要被优化了
key

显示mysql查询中实际使用到的索引,如果没有使用索引,显示为null

  • 注意 : 查询中如果使用了覆盖索引,在该索引仅出现在key列表中
key_length

在这里插入图片描述

ref

表示上述表中的连接匹配条件,即哪些条件或常量被用于查找索引上的值

rows

返回估算的结果集数目,并不是一个准确的值

数据量比较多的情况下:

要处理的数据量比较小:

对于数据每次操作十几条几十条这种情况,可以采用分库分表的方式

要处理的数据量比较大:

对于每次操作一个月或一个季度这样的数据量,可以采用分区的方式批处理,如果数据量再大,就是大数据了

InnoDB的索引实现

在innodb中,表数据文件本身就是B+tree组织中的一部分,这个树的叶节点data保存了完整的数据记录,这个索引的key是数据表中的主键,所以,innodb表数据文件本身就是主索引.

如下图所示,可以看到叶子节点保存完整数据,这种索引叫做聚集索引
在这里插入图片描述
因为InnoDB的数据文件本身就按主键聚集,所以innodb要求表必须具备主键:
创建表时指定一列作为主键列
Mysql会自动选择一个可以唯一被标识的列作为主键
MySql会自动为表生成一个隐含的字段作为主键,这个字段的长度为6字节,类型为长整型

innodb所有辅助索引的data都是主键,所以通过辅助索引查询实际上是查询了两次才查询到对应的数据
如下图所示:
在这里插入图片描述
mysql 中的索引分为一级索引和二级索引:
一级索引: 以唯一主键为索引,通过where中的条件是主键,查找到数据
二级索引: 以除唯一主键以为的其他索引(辅助索引,组合索引等),在查询的时候,where中的条件字段是非主键的时候,先通过这个字段查询到主键,然后根据主键查找到数据.所以需要查询两次b+tree.
覆盖索引:一个索引中包含所有要查询的值的值,那个这个索引就是覆盖索引,查询的时候只需要查询一次就可以查询到要查的值
例如:
主键 : a
非主键 : b c
关于a 的索引是 一级索引
关于b 的索引是 二级索引
关于b c 的索引是 二级索引
关于a b 的索引是 二级索引

二级索引查询情况如下图所示:

在这里插入图片描述

MYSIAM引擎索引类型

mysiam引擎的索引也是分为一级索引和二级索引

一级索引:
在这里插入图片描述
二级索引:
在这里插入图片描述
MySAIM 的一级索引和二级索引一样,叶子节点上存储的都是数据所在磁盘的路径,当查询的时候,先找到地址,然后从地址中找到数据

MySAIM和Innodb 缓存区别:

Mysaim 的索引和数据分别放在不同文件中
Innodb的索引和数据放在同一个文件里
其中,innodb中的二级索引中存放的是一级索引的key

执行计划的目的就是为了优化sql语句执行效率

猜你喜欢

转载自blog.csdn.net/kai3123919064/article/details/88877608