0
点赞
收藏
分享

微信扫一扫

Mysql学习 (一)——SQL优化

静悠 2022-04-14 阅读 102

SQL优化

Mysql 架构介绍

数据库引擎

在这里插入图片描述

性能下降的原因

在这里插入图片描述

性能下降主要有两个表现: 执行时间长、 等待时间长

可能原因有以下四种:

  1. 查询语句写的烂
  2. 发生索引失效
  3. 关联查询太多join
  4. 服务器调优及各个参数设置

常见通用的Join查询

SQL执行顺序

机读顺序
在这里插入图片描述

Join图

在这里插入图片描述

inner join

内连接

在这里插入图片描述

left join

在这里插入图片描述

right join

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

索引

什么是索引

Mysql官方对索引的定义是,帮助Mysql高效获取数据的数据结构。
通俗来讲,索引就相当于字典的目录。

在这里插入图片描述

数据本身之外,数据库还维护着一个满足特定查找算法 的数据结构,这些数据结构以某种方式执行数据,这样就可以在这些数据机构的基础上实现高级查找算法。这种数据结构就是索引

一般索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。我们常说的索引,如果没有特别指明,都是指B树(多路搜索树)结构组织的索引。其中聚集索引、辅助索引、覆盖索引、复合索引、前缀索引默认都是使用B+树。

优势和劣势

优势:

  1. 类似大学图书馆建书目索引,提高数据检索的效率,减低数据库的IO成本
  2. 通过索引列对数据进行排序,降低了数据排序的成本,减低CPU消耗。

劣势:

  1. 索引也是 一张表,该表保存了主键和索引字段,并指向实体表的记录,索引列也是要占用空间的
  2. 虽然索引提高了查询 速度,同时却降低了更新表的速度。如对表的insert、update和delete。因为更新表时候,不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段。
  3. 对于大量数据的表,还需要花费时间研究最优秀的索引。

索引的分类

单值索引:一个索引只包含单个列,一个表 可以有多个单值索引。
唯一索引: 索引列的值必须唯一,但允许有空值。
复合索引: 即一个索引可以包含多个列。

基本雨

Mysql索引结构

BTree索引

在这里插入图片描述

在这里插入图片描述

真实情况是,3层的B+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的。

Hash索引、full-text全文索引、R-Tree索引

建立索引

哪些情况需要建立索引

  1. 主键自动创建唯一索引
  2. 频繁作为查询条件的字段应该创建索引
  3. 查询中与其他表关联的字段,外键关系建立索引
  4. 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
  5. 查询中统计或者分组的字段

哪些情况不适合建立索引

  1. 表记录太少
  2. 频繁更新的字段不适合建立索引
  3. 经常增删改的表
  4. 如果某个数据列包含许多重复内容,为他建立索引就没有太大效果。

基本语法

在这里插入图片描述

在这里插入图片描述

性能分析

Mysql常见瓶颈

在这里插入图片描述

Explain

是什么

执行计划

在这里插入图片描述

字段

id

select_type

DERIVED

在这里插入图片描述
在这里插入图片描述

type字段

注意以上都是在 建立索引的情况。

system、const
在这里插入图片描述

eq_ref
在这里插入图片描述

ref

在这里插入图片描述

range
在这里插入图片描述
index

在这里插入图片描述

key_len

在这里插入图片描述

ref

在这里插入图片描述

rows

在这里插入图片描述

extra字段

在这里插入图片描述

using index
在这里插入图片描述

Case

在这里插入图片描述

单表优化

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述在这里插入图片描述

两表索引优化

在这里插入图片描述

主表不加,从表需要加索引。

都加了会有临时表。

三表优化

在这里插入图片描述

join语句的优化:

尽可能减少Join语句中的NestedLoop的循环总次数:“”永远用小结果驱动打的结果集“”
优先优化NestedLoop的内层循环。
抱枕Join语句中被驱动表上Join条件字段已经被索引
当无法保证被驱动表的Join条件字段被索引且内存资源充足的前提下,不要太吝惜JoinBuffer的设置

索引失效

在这里插入图片描述

索引失效的情况

在这里插入图片描述

建立(name,age,position)复合索引

  1. 全值匹配最佳
    在这里插入图片描述

  2. 最左前缀法则: 如果索引了多列,要 遵守最左前缀法则,指的是查询 从索引的最左前列开始 并且不跳过索引中的 列。

在这里插入图片描述

由于跨过中间列,索引失效。
在这里插入图片描述是只使用了age索引,当做查询条件。

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

在这里插入图片描述

  1. 存储引擎不能使用索引中范围 条件右边的列

在这里插入图片描述

  1. 尽量使用 覆盖索引(只访问索引的查询(索引列与查询列一致)),减少回表查询

在这里插入图片描述
6. mysql 在使用不等于(!= 或者 <>)的时候无法使用 索引将会导致全表扫描

在这里插入图片描述

  1. is null , is not null 也无法使用索引
    在这里插入图片描述

  2. like 以通配符开头(%abc)mysql索引失效会变成全表扫描的操作。
    在这里插入图片描述

解决like ‘%字符串%’ 时索引不被使用的方法

在这里插入图片描述

上面方案虽然解决了索引失效问题,但是查询结果不是我们想要的
在这里插入图片描述或者
在这里插入图片描述

注意这种不是索引覆盖

在这里插入图片描述

  1. 字符串不加单引号会导致失效

在这里插入图片描述
10. 少用or

在这里插入图片描述

小结

  1. 带头大哥不能死,中间兄弟不能断。永远要符合最佳左前缀原则
  2. 索引列上无计算
  3. like % 加右边
  4. 范围之外全失效,少用* 多具体。.
  5. 字符串上有引号

在这里插入图片描述

在这里插入图片描述

面试题

题目SQL
在这里插入图片描述建立索引 (c1,c2,c3,c4)

c1 char(10)长度为3* 10 + 1(null )

在这里插入图片描述

在这里插入图片描述第一条SQL语句,这里c3只做排序用,不作为索引使用,所以没记录,key_len 为c1和c2的长度为62.

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

order by
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

group by,分组前需要排序,而内排序会有临时表的产生。

一般性建议

举报

相关推荐

0 条评论