整体结构图

和其它数据库相比,MySQL 有点与众不同,它的架构可以在多种不同场景中应用并发挥良好作用。主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离。这种架构可以根据业务的需求和实际需要选择合适的存储引擎。

从架构图上看我们可以把MySQL大致分成4层,分别是连接层,服务层,引擎层和存储层

连接层:最上层是一些客户端和连接服务,包含本地 sock 通信和大多数基于客户端/服务端工具实现的类似于 tcp/ip 的 通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证 安全接入的客户端提供线程。同样在该层上可以实现基于 SSL 的安全链接。服务器也会为安全接入的每个客户端验 证它所具有的操作权限。

服务层:

引擎层:存储引擎层,存储引擎真正的负责了 MySQL 中数据的存储和提取,服务器通过 API 与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要进行选取。

存储层:数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互。

MyISAM和InnoDB

和引擎相关的SQL

show engines       :查看所有的数据库引擎
show variables like '%storage_engine%'  :查看默认的数据库引擎

索引优化分析

作为一名后端程序员,写出性能优良的SQL是我们最终的目的。我们都知道,影响性能的往往都是一些查询语句,当查询的数据量达到一定级别时,有的时候我们能明显的感觉到系统变慢,所以接下来要讲的优化都是针对查询语句而言的。MySQL为我们提供了一个优化的方向,那就是索引,索引优化是一个后端程序员必须要掌握的技能点。

索引

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。我们可以简单理解为索引就是排好序的快速查找数据结构。对于数据库系统而言,在数据之外,还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构上实现高级查找算法。下图就是一种可能的索引方式示例:

左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址。为了加快 Col2 的查找,可以维护一个 右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在一定的复杂度内获取到相应数据,从而快速的检索出符合条件的记录。

一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。

索引原理

初始化介绍
一颗 b 树,浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块 1 包含数据项 17 和 35,包含指针 P1、P2、P3;P1 表示小于 17 的磁盘块,P2 表示在 17 和 35 之间的磁盘块,P3 表示大于 35 的磁盘块。

真实的数据存在于叶子节点即 3、5、9、10、13、15、28、29、36、60、75、79、90、99。非叶子节点不存储真实的数据,只存储指引搜索方向的数据项,如 17、35 并不真实存在于数据表中。

【查找过程】
如果要查找数据项 29,那么首先会把磁盘块 1 由磁盘加载到内存,此时发生1次 IO,在内存中用二分查找确定 29 在 17 和 35 之间,锁定磁盘块 1 的 P2 指针,通过磁盘块 1 的 P2 指针的磁盘地址把磁盘块 3 由磁盘加载到内存,发生第2次 IO,29 在 26 和 30 之间,锁定磁盘块 3 的 P2 指 针,通过指针加载磁盘块 8 到内存,发生第3次 IO,同时内存中做二分查找找到 29,结束查询,总计3次 IO。

真实的情况是,3 层的 b+树可以表示上百万的数据,如果上百万的数据查找只需要3次 IO,性能提高将是巨大的, 如果没有索引,每个数据项都要发生一次 IO,那么总共需要百万次的 IO,显然成本非常非常高。

上面是通过Btree(B-tree)的方式实现的索引,接下来我们再看一种B+tree的数据结构实现的索引方式

B+Tree 与 B-Tree 的区别

1.B-树的关键字和记录是放在一起的,叶子节点可以看作外部节点,不包含任何信息;B+树的非叶子节点中只有关键字和指向下一个节点的索引,记录只放在叶子节点中。
2.在 B-树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;而 B+树中每个记录的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字。从这个角度看 B- 树的性能好像要比 B+树好,而在实际应用中却是 B+树的性能要好些。因为 B+树的非叶子节点不存放实际的数据, 这样每个节点可容纳的元素个数比 B-树多,树高比 B-树小,这样带来的好处是减少磁盘访问次数。尽管 B+树找到 一个记录所需的比较次数要比 B-树多,但是一次磁盘访问的时间相当于成百上千次内存比较的时间,因此实际中 B+树的性能可能还会好些,而且 B+树的叶子节点使用指针连接在一起,方便顺序遍历(例如查看一个目录下的所有 文件,一个表中的所有记录等),这也是很多数据库和文件系统使用 B+树的缘故。

思考:为什么说 B+树比 B-树更适合实际应用中操作系统的文件索引和数据库索引?

1) B+树的磁盘读写代价更低;B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对 B 树更小。如果把所有同一内部结点 的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就 越多。相对来说 IO 读写次数也就降低了。

2) B+树的查询效率更加稳定;由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须 走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

索引的优势和劣势

优势:

1.提高数据检索的效率,降低数据库的IO成本。

2.通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

劣势:

1.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为 更新所带来的键值变化后的索引信息。

2.实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间 的。

MySQL索引

分类

单值索引:一个索引只包含单个列,一个表可以有多个单值索引

唯一索引:索引列的值必须唯一,但允许有空值

主键索引:设定为主键后数据库会自动建立索引

复合索引:一个索引包含多个列

语法

索引的创建时机

适合创建索引的情况

主键自动建立唯一索引;
频繁作为查询条件的字段应该创建索引
查询中与其它表关联的字段,外键关系建立索引
单键/组合索引的选择问题, 组合索引性价比更高
查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度  查询中统计或者分组字段

不适合创建索引的情况

表记录太少

经常增删改的表或者字段

Where条件里用不到的字段不创建索引

过滤性不好的不适合建索引

Explain性能分析

语法:Explain + SQL语句

返回结果信息如下所示:

关于这10个参数的具体解释如下:

id:select 查询的序列号,包含一组数字,表示查询中执行 select 子句或操作表的顺序。有三种情况

id 相同,执行顺序由上至下

id不同,id 不同,如果是子查询,id 的序号会递增,id 值越大优先级越高,越先被执行

id有相同也有不同,id 如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id 值越大,优先级越高,越先执行衍生 =          DERIVED

      关注点:id 号每个号码,表示一趟独立的查询。一个 sql 的查询趟数越少越好。

select_type:代表查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询。

table:表名

type:查询的访问类型。是较为重要的一个性能指标,结果值从最好到最坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index >all

一般来说,得保证查询至少达到 range 级别,最好能达到 ref。

possible_keys:显示此次查询中可能应用到的在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用。

key:实际使用的索引。如果为NULL,则没有使用索引。

key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。 key_len 字段能够帮你检查是否充分的 利用上了索引。ken_len 越长,说明索引使用的越充分。

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值。

rows:rows 列显示 MySQL 认为它执行查询时必须检查的行数。越少越好!

Extra:其他的额外重要的信息。

Using filesort:说明 mysql 会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL 中无法利用                                        索引 完成的排序操作称为“文件排序”。

Using temporary:使了用临时表保存中间结果,MySQL 在对查询结果排序时使用临时表。常见于排序 order by 和分组查询                                             group by

Using index:Using index 代表表示相应的 select 操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率                                     不错! 如果同时出现 using where,表明索引被用来执行索引键值的查找;如果没有同时出现 using where,表                                     明索引只是用来读取数据而非利用索引执行查找。

Using where:表明使用了 where 过滤。

Using join buffer:使用了连接缓存。

impossible where:where 子句的值总是 false,不能用来获取任何元组。

当extra出现了Using filesort和Using temporary就表明我们应该对sql进行优化了,最好的情况是出现using index

单表索引优化原则

1.全职匹配我最爱指的是,查询的字段按照顺序在索引中都可以匹配到!

2.最佳左前缀法则:过滤条件要使用索引必须按照索引建立时的顺序,依次满足,一旦跳过某个字段,索引后面的字段无法被用

3.不要在索引列上做任何计算:不在索引列上做任何操作(计算、函数、(自动 or 手动)类型转换),会导致索引失效而转向全表扫描。

4.不要在查询列上使用了函数:等号左边无计算

5.查询列上不要做类型转换:等号右边无转换!

6.索引列上不能有范围查询:将可能做范围查询的字段的索引顺序放在最后,不然它后面的都会失效

7.尽量使用覆盖索引:查询列和索引列保持一致,少用select *

8.使用不等于(!= 或者<>)的时候会导致索引失效

9.字段的 is not null 和 is null:is not null 用不到索引,is null 可以用到索引。

10.like 的前后模糊匹配:前缀不能出现模糊匹配,即like后面不要出%,如果一定要出,则尽量使用索引覆盖

11.减少使用or:使用 union all 或者 union 来替代:

记忆口诀

全职匹配我最爱,最左前缀要遵守; 带头大哥不能死,中间兄弟不能断; 索引列上少计算,范围之后全失效; LIKE 百分写最右,覆盖索引不写*; 不等空值还有 OR,索引影响要注意; VAR 引号不可丢,SQL 优化有诀窍。

关联查询优化原则

在优化关联查询时,只有在被驱动表上建立索引才有效!

left join 时,左侧的为驱动表,右侧为被驱动表!

inner join 时,mysql 会自己帮你把小结果集的表选为驱动表。straight_join 效果和 inner join 一样,但是会强制将左侧作为驱动表!

子查询尽量不要放在被驱动表,有可能使用不到索引;left join时,尽量让实体表作为被驱动表。能够直接多表关联的尽量直接关联,不用子查询!

排序和分组优化原则

order by优化

1.无过滤,不索引。where,limt 都相当于一种过滤条件,所以才能使用上索引!

2.顺序错,必排序:where 两侧列的顺序可以变换,效果相同,但是 order by 列的顺序不能随便变换!

3.方向反,必排序:排序的字段有多个时,要么都遵守升序要么都遵守降序,否则必然Using filesort

4.当范围条件和 group by 或者 order by 的字段出现二选一时 ,优先观察条件字段的过滤数量,如果过滤的 数据足够多,而需要排     序的数据并不多时,优先把索引放在范围字段上。反之,亦然。

截取查询分析

当系统运行缓慢的时候,我们想知道当前哪些SQL查询缓慢,这个时候我们就需要借助一些工具找出那些我们认为慢的SQL进行分析优化

慢查询日志

(1)MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。

(2)具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10秒以上的语句。

(3)由他来查看哪些SQL超出了我们的最大忍耐时间值,比如一条sql执行超过5秒钟,我们就算慢SQL,希望能收集超过5秒的sql,结合之前explain进行全面分析。

使用方式

默认情况下,MySQL 数据库没有开启慢查询日志,需要我们手动来设置这个参数。

当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。 慢查询日志支持将日志记录写入文件。

开启设置

除了这种方式,我们还可以通过其他方式来进行SQL分析,比如show profile

show profile

开启profile

使用profile

MySQL的锁机制

分类

从对数据操作的类型分:读锁(read)和写锁(write),读锁为共享锁,针对同一份数据,多个读操作可以同时进行而不会互相影响写                                            锁

后端程序员必须要懂的MySQL数据库相关推荐

  1. sqlite 查询 支持多用户同时_开源时代的后端程序员必须要了解的一个数据库SQLite...

    在过去工作的十年里,我主要使用了三大主流的数据库,SqlServer.MySql.Oracle.小型数据库还使用过Access.因为一直做后端开发的原因,很少使用SQLite数据库,因为我一直认为SQ ...

  2. [转]后端程序员必备:书写高质量SQL的30条建议

    以下文章来源于捡田螺的小男孩 ,作者捡田螺的小男孩 转载:<后端程序员必备:书写高质量SQL的30条建议> 前言 本文将结合实例demo,阐述30条有关于优化SQL的建议,多数是实际开发中 ...

  3. Java后端程序员1年工作经验总结

    java后端1年经验和技术总结(1) 1.引言 毕业已经一年有余,这一年里特别感谢技术管理人员的器重,以及同事的帮忙,学到了不少东西.这一年里走过一些弯路,也碰到一些难题,也受到过做为一名开发却经常为 ...

  4. 聊聊后端程序员的知识体系-第一篇

    聊聊后端程序员的知识体系-第一篇 原文链接:https://www.fpthinker.com/backend_knowledge_architecture/knowledge.htmll 亲爱的读者 ...

  5. Java后端程序员1年工作经验和技术总结

    本文转载自:Java后端程序员1年工作经验和技术总结 1.引言  毕业已经一年有余,这一年里特别感谢技术管理人员的器重,以及同事的帮忙,学到了不少东西.这一年里走过一些弯路,也碰到一些难题,也受到过做 ...

  6. Java后端程序员技术栈

    Java后端程序员技术栈 它可以是知识提纲,便于快速复习与查阅 它也可以是你的学习规划,帮助小白快速了解学Java要走的路(当然你也可以选择搭配我的学习路线一起享用!) 相关链接: <gitee ...

  7. java程序员需要会前端吗_一个后端程序员,需要掌握前端技术吗?

    一个后端程序员,需要掌握前端技术吗? JSP时代 8年前,刚刚进入编程这个行业,当时的Web开发使用古老的SSH框架+JSP.那个时候,几乎所有的Java程序员都要懂得如何写JavaScript.如何 ...

  8. 后端程序员的前端工具

    后端程序员的前端工具 在总结监控系统时,其中有一点:将API 接口开发转变为SQL 查询,支持sql算子.这样后端开发工程师就不用疲于奔命提供查询服务了.听说阿里巴巴的产品工程师也要学习SQL语句,为 ...

  9. 写给后端程序员的HTTP缓存原理介绍

    通过Internet获取资源既缓慢,成本又高.为此,Http协议里包含了控制缓存的部分,以使Http客户端可以缓存和重用以前获取的资源,从而优化性能,提升体验.虽然Http中关于缓存控制的部分,随着协 ...

最新文章

  1. 3.7.1 读取输入
  2. office365为新建账号发送欢迎邮件
  3. xmanager 开启X11转发失败问题解决
  4. 16万辆汽车已经用上中国“车规AI第一芯”,量产还在加速
  5. 2016年-2020年 考研 国家线汇总
  6. 查询分析器下如何备份数据库
  7. html:(18):文本输入框,密码输入框,文本域
  8. 通话时自动中断音乐播放_您知道用户在何处以及为何中断通话吗?
  9. 关于成本核算方法、步骤、成本分析的简单回复
  10. SXF2019子串模糊匹配
  11. Android bitmap.recycle()导致trying to use a recycled bitmap报错分析
  12. uniapp h5微信分享
  13. 以太坊教程-使用 remix-ide 开发以太坊智能合约
  14. Android关闭屏幕,但不休眠
  15. 第三方支付宝API应用流程
  16. MATLAB 动态规划
  17. 业余时间零基础自学编程,9 个月后我成为一名软件工程师
  18. java实现PDF转图片功能,附实例源码!
  19. java根据拼音获取声调_Pinyin4j的基本用法 获得拼音的声调
  20. 看完这篇Linux基本的操作你就会了

热门文章

  1. 数据库的基本常用命令
  2. 5G - NR RLC协议阅读笔记4 - 三个重要定时器的理解
  3. 如何用r语言分析数据
  4. 2021年上半年软件设计师下午真题及答案解析(三)
  5. 刨根问底:Kafka 到底会不会丢数据?
  6. 【Linux】vim文本编辑器的使用
  7. Android无障碍服务开发
  8. 美国的Harvey Mudd College
  9. iOS开发者比较好用的几个工具
  10. mysql数据库密码的修改