Mysql学习 ——SQL优化

Posted JohnnyLin00

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql学习 ——SQL优化相关的知识,希望对你有一定的参考价值。

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,分组前需要排序,而内排序会有临时表的产生。

一般性建议

以上是关于Mysql学习 ——SQL优化的主要内容,如果未能解决你的问题,请参考以下文章

MySQL性能优化

MySQL批量SQL插入性能优化

MySQL批量SQL插入性能优化

MySQL批量SQL插入性能优化

Mysql慢SQL分析及优化

MySQL批量SQL插入性能优化详解