MySQL数据库高级 & SQL优化

——mysql架构

  • 连接层
  • 服务层
    • sql接口
    • 解析器
    • 优化器
    • 查询缓存
  • 引擎层
    • InnoDb 存储引擎三大特性
      • 自适应 Hash 索引(Adatptive Hash Index,AHI):InnoDB存储引擎内部自己去监控索引表,如果监控到某个索引经常用,那么就认为是热数据,然后内部自己创建一个hash索引,称之为自适应哈希索引,创建以后,如果下次又查询到这个索引,那么直接通过hash算法推导出记录的地址,直接一次就能查到数据
      • Buffer Pool(BP):为了提高访问速度,MySQL预先就分配/准备了许多这样的空间,为的就是与MySQL数据文件中的页做交换,来把数据文件中的页放到事先准备好的内存中。数据的访问是按照页(默认为16KB)的方式从数据文件中读取到 buffer pool中。Buffer Pool按照最少使用算法(LRU),来管理内存中的页
      • 双写缓冲区(DoubleWrite Buffer):是一个位于系统表空间的存储区域,在写入时,InnoDB先把从缓冲池中的得到的page写入系统表空间的双写缓冲区。之后,再把page写到.ibd数据文件中相应的位置。如果在page写入数据文件的过程中发生意外崩溃,InnoDB在稍后的恢复过程中在doublewrite buffer中找到完好的page副本用于恢复;它的主要作用是为了避免partial page write(部分页写入)的问题。因为InnoDB的page size一般是16KB,校验和写入到磁盘是以page为单位进行的。而操作系统写文件是以4KB作为单位的,每写一个page,操作系统需要写4个块,中间发生了系统断电或系统崩溃,只有一部分页面是写入成功的。这时page数据出现不一样的情形,从而形成一个"断裂"的page,使数据产生混乱
  • 存储层

——基本概念

标识列(自增长列)

  • 可以不用手动插入值,系统提供默认的序列值
  • 标识列不是必须和主键搭配的,但要求是个key(主键、唯一索引、外键)
  • 一个表至多有一个标识列
  • 标识列的数据类型只能是数值型

主键和唯一索引的区别

保证唯一性是否允许为空一个表可以有多少个是否可组合
主键×至多有一个
唯一√(但只允许一个为null)可以有多个

存储过程和函数

  • 类似 Java 中的方法,一组预先编译好的SQL语句,批处理语句
  • 提高代码的重用性
  • 简化操作
  • 减少了编译次数并且减少和数据库服务器的连接次数,提高效率
  • 一张表一般不超过5个索引

聚簇索引

  • 表示数据行和相邻的键值聚簇的存储在一起
  • 好处:按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不用从多个数据块中提取数据,节省大量的IO操作
  • 只有InnoDB存储引擎支持聚簇索引
  • 一个表只能有一个聚簇索引,一般情况都是主键
  • 为了充分利用聚簇的特性(顺序排列),通常都选择有序id,不建议用无序id(uuid)

——索引

特性

  • 是一种数据结构(排好序的快速查找数据结构)
  • 目的:提高查找效率
  • 索引往往以索引文件的形式存储在磁盘
  • 平常索引都是指B数(多路搜索树)结构组织的索引
  • 复合索引优先于单值索引,高并发下倾向创建组合索引

优点

  • 提高数据检索的效率,降低了数据库的IO成本
  • 降低数据排序的成本,降低了CPU的消耗

缺点

  • 需要占空间
  • 降低更新表的速度(增删改)
  • 索引只是提高效率的一个因素,需要花时间研究建立最优秀的索引

结构

  • BTree / B+ Tree 索引
  • Hash索引
  • 全文索引
  • R-Tree索引

检索原理
- 磁盘块,数据项,指针
- 真实数据值存在于叶子节点,非叶子节点不存储真实的数据,只存储指引搜索方向的数据项
- 数据项的广度增多,深度减少,避免多次IO,通常为3层

——sql 优化

Explain执行计划表头字段

使用Explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句,分析你的查询语句或者表结构的性能瓶颈

  • id:操作表的顺序,表的读取顺序
    • id不同,id值越大优先级越高,越先被执行
    • id相同,顺序执行
  • select_type:查询类型
    • simple:不包含子查询或者union
    • primary:查询包含任何复杂的子部分,最外层则标记为主查询
    • subquery:子查询
    • derive:衍生表,临时表(derive1,1则为id)
    • union:第二个select出现在union后,则标记union
    • union result:从union表中获取结果的select
  • table:表名
  • type:访问类型
    1. system:表中只有一行
    2. const:直接通过索引一次就找到,用于比较主键或者唯一索引,匹配一行数据,能将该查询转换为一个常量
    3. eq_ref:唯一性索引扫描,表中只有一条记录匹配,常见于主键或者唯一索引扫描,常用于联表查询
    4. ref:非唯一性索引扫描,返回匹配单独值的所有行
    5. range:只检索给定范围的行,where条件中出现了between、>、<、in
    6. index:全索引扫描
    7. all:全表扫描
    • 至少达到range级别
  • possible_keys:可能应用到这张表的索引
  • key:实际使用到的索引
  • key_len:索引使用的字节数,显示的值为索引字段的最大可能长度,并非实际使用长度
  • ref:具体索引的哪一列,可能的话,会是一个常量
  • rows:找到所需要的记录所需读取的行数
  • Extra:包含不适合在其他列中显示但十分重要的额外信息
    • Using filesort:无法利用索引完成的排序操作,称为“文件排序”,需要优化
    • Using temporary:使用临时表保存结果,常见于排序和分组,耗性能
    • Using index:表示查询操作中用到 覆盖索引 ,若同时出现Using where,则索引被用来执行索引键值查找,否则,索引只用来读取数据
    • 覆盖索引:查询的列被所建的索引完全覆盖(匹配),常见于组合索引

索引优化

多表索引

  • 左连接加右表字段索引,右连接加左表字段索引

索引失效

  • 最左匹配原则: 建立组合索引(ABC),查询从索引的最左前列开始并且不跳过索引中的列
  • 不在索引列上做任何操作(计算、函数、自动/手动类型转换)
  • 不能使用索引中范围条件右边的列(B> <),导致C失效
  • 尽量使用覆盖索引(只访问索引的查询),减少select *
  • 在使用不等于(!= 或者 <>)的时候索引失效
  • is null,is not nul
  • like 模糊查询
    • %只写在右边不会导致索引失效
    • Q:like ‘%字符串%’,保证索引还不失效的方法?
    • A:利用覆盖索引可解决该问题
  • 字符串不加单引号,发生数据类型隐式转换
  • 少用or

group by 基本上都需要排序,会有临时表产生

——查询截取分析

流程

  1. 观察:查看生产的慢SQL情况
  2. 慢查询的开启并捕获
  3. explain + 慢SQL分析
  4. show profile 查询SQL在Mysql服务器里面的执行细节和生命周期情况
  5. SQL数据库服务器的参数调优

慢查询日志

  • 记录在Mysql中响应时间超过阈值时间的语句,具体指运行时间超过long_query_time值的SQL,会被记录到慢查询日志中
  • 默认不开启,开启会带来一定的性能影响
  • 日志分析工具:mysqldumpslow,通过命令能够获取慢查询日志中条件的sql(访问次数、查询时间等)

小表驱动大表: 当子查询B表数据集小于主查询A表时,用in,否则,用exist

group by:先排序后分组,遵照索引建的最佳左前缀原则

——show profile

  • 是mysql提供可以用来分析当前的会话中语句执行的资源消耗情况(CPU、IO),查看sql执行的整个生命周期及分别耗时情况
  • 注意Status字段以下值
    • converting HEAP to MyISAM:查询结果的太大,内存不够用了往磁盘上搬
    • Creating tmp table:创建临时表(拷完数据到临时表,用完再删除,一般发生在group by)
    • Copy to tmp table on disk:把内存中临时表复制到磁盘
    • locked:锁表

——数据库锁

表锁

  • 读锁(共享锁)
  • 写锁(排它锁、独占锁)
  • 读锁会阻塞写,但不会阻塞读。写锁会把读和写都阻塞

行锁变表锁情况:索引失效的情况下的操作数据未提交,其他会话再进入查询时会被阻塞

间隙锁: 当用 范围条件 而不是相等条件检索数据,请求共享或排他时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”;InnoDb也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)

——主从复制

原理

  1. master 将改变记录到二进制日志(binary log),这记录过程叫做二进制日志事件(binary log events)
  2. slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
  3. slave 重做中继日志的事件,将改变应用到自己的数据库中,MySQL复制是异步、串行化的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序少年不秃头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值